x86汇编代码中的指针引用

时间:2015-04-23 04:24:25

标签: c pointers assembly x86 att

我正在阅读我的教科书,它有交换功能的代码:

在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存储在%edx而不是地址A中?这不是括号在汇编中做的吗?

或者这是否意味着当指针被推入堆栈时,指针的地址被推上而不是它所持有的值,因此8(%ebp)技术上保持& xp?

只是想澄清我的理解是否正确。

2 个答案:

答案 0 :(得分:5)

xp是一个指针。它有一个四字节值。该值由调用函数压入堆栈。您未显示的函数序言在ebp中设置了基指针。 xp的值存储在相对于该基指针的偏移量8处。

因此,第一行代码取消引用基本指针,如括号所示,偏移量为8,以检索xp(这是一个指向的地址)一个int)并将其放入edx

第二行代码使用edx中的地址来检索int的值,并将该值放入eax。请注意,函数返回值将是eax中的值。

第三行取消引用基址指针,偏移量为12,以获得y的值。

第四行使用edx中的地址将y放在xp指向的位置。

答案 1 :(得分:2)

%bp是堆栈基指针,在我可以访问堆栈上的任何内容之前必须将其引用。所以movl 8(%bp),%edx`获取当前堆栈帧中偏移量8的值。

这个值是一个指针,因此我们必须取消引用它才能访问其内容,无论是读取还是写入。

OTOH,y是一个int,所以要获得它只是movl 12(%ebp), %ecx并且不需要进一步的actoin。

所以movl %ecx, (%edx)是正确的:将ecx中存储的值放到edx指向的内存中。