2

我试图通过取消引用前两个寄存器,然后将结果存储在第三个寄存器中,在 ARM Assembly 中将两个寄存器添加在一起。

目前我有3个变量和一个函数,如下所示;

extern void my_function(int* x, int* y, int* total);

int main(void){
   int x = 1;     //R0
   int y = 2;     //R1
   int total = 0; //R2

   while(1){
      my_function(&x, &y, &total);
      printf("\x1b[5;5HTotal = %d, total");
   }
}

这个函数执行以下操作

对于前两个寄存器,我试图取消引用它们,将它们加在一起并将结果存储在第三个寄存器中。这是我的汇编代码;

ldr r4, [r0]    @ Dereference r0, and store the address in R4
ldr r4, [r1]    @ Dereference r1, and store the address in R4
add r2, r0, r1  @ Add r0 & r1 together, and store in R2
str r4, [r2]    @ Store r2 address in r4

当我打印出来时,答案是 0。我的问题是,当我在汇编中执行前两行时,是否ldr r4, [r0] 被替换ldr r4, [r1]为导致输出为 0 的?他们每个人都需要存储在自己的寄存器中吗?或者我只是基本上打印出总数(r2)?

4

1 回答 1

3

永远不要在没有文档的情况下启动汇编语言项目。然后实际阅读该文档。

你有一个 C 编译器,所以你可以看到它做了什么,然后弄清楚每条指令在做什么,然后找出你哪里出错了。

void my_function(int* x, int* y, int* total)
{
    *total = *x + *y;
}

可以根据命令行选项生成

my_function:
    ldr r3, [r0]
    ldr r1, [r1]
    add r3, r3, r1
    str r3, [r2]
    bx  lr

您还必须了解用于进行 C/asm 转换的编译器的调用约定。对于这种情况,在 arm 中,r0 是 x 的地址,r1 是 y 的地址,r2 是总的地址。

ldr r4, [r0]    @ read the value of x into r4
ldr r4, [r1]    @ read the value of y into r4 losing/discarding the value of x
add r2, r0, r1  @ add the pointers together destroying the pointer to total
str r4, [r2]    @ store the value of y into a location destroying whatever was there

根据典型的调用约定(编译器可以选择使用/创建他们想要的任何内容,因此您需要了解约定),因为 arm r4 是易变的,因此您需要将其推送到堆栈上,您不能在函数期间破坏其中的内容.

因为您的程序不修改总变量并且它是 .bss 的一部分,所以引导程序已将总归零,而您只是打印出该值,这就是为什么您看到零您的代码与它无关。x 的地址加上 y 的地址成为总地址的几率非常小,基本上为零(但程序可以在它工作的地方制作),所以你的代码再次与总的零值无关.

于 2020-02-09T16:57:09.327 回答