x86 汇编代码中的指针引用
Pointer Deferencing in x86 Assembly Code
我正在阅读我的教科书,它有交换函数的代码:
在 C:
int exchange(int *xp, int y) {
int x = *xp;
*xp = y;
return x;
}
在带有注释的 x86 程序集中:
// xp is at %ebp + 8, y at %ebp + 12
movl 8(%ebp), %edx // get xp
movl (%edx), %eax // get x at xp
movl 12(%ebp), %ecx // get y
movl %ecx, (%edx) // store y at xp
所以根据我的理解,如果 int* xp 指向地址 A 处的 int I,那么第一行汇编代码将 A 存储在 %edx 处。然后它在第二行被取消引用并存储在 %eax.
如果这是真的,我想知道为什么第 1 行的“8(%ebp)”不取消引用指针,将 int I 存储在 %edx 而不是地址 A 中?这不是括号在汇编中的作用吗?
或者这是否意味着当指针被压入堆栈时,指针的地址被压入而不是它所持有的值所以 8(%ebp) 在技术上持有 &xp?
只是想澄清一下我的理解是否正确。
xp
是一个指针。它有一个四字节的值。该值被调用函数压入堆栈。您没有显示的函数序言在 ebp
中设置了一个基指针。 xp
的值存储在相对于该基指针的偏移量 8 处。
所以第一行代码取消引用基指针,如括号所示,偏移量为 8 以检索 xp
的 value(这是指向 int 的地址)并将其放入 edx
.
第二行代码使用 edx
中的地址检索 int
的值,并将该值放入 eax
。请注意,函数 return 的值将是 eax
.
第三行解引用基指针,偏移量为12,得到y
的值。
第四行使用edx
中的地址将y
放在xp
指向的位置。
%bp
是堆栈基址指针,在我可以访问堆栈上的任何内容之前必须对其进行引用。所以 movl
8(%bp),%edx` 获取位于当前堆栈帧中偏移量 8 的值。
这个值是一个指针,所以我们必须取消引用它才能访问它的内容,无论是读还是写。
OTOH,y
是一个整数,所以要得到它只是 movl 12(%ebp), %ecx
并且不需要进一步的作用。
所以movl %ecx, (%edx)
是完全正确的:将存储在ecx
中的值放到edx
指向的内存中。