【问题标题】:Pointer Deferencing in x86 Assembly Codex86 汇编代码中的指针引用
【发布时间】:2015-07-01 01:26:27
【问题描述】:

我正在阅读我的教科书,里面有交换函数的代码:

在 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?

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

【问题讨论】:

  • Ebp 是堆栈帧的地址,所有参数都在其中。 Ebp+8 是 xp 值的地址(即 int 的地址)。从技术上讲,是的——ebp+8 == &xp。
  • 这是否意味着当指针被压入堆栈时,指针的地址被压入而不是它所持有的值 – 不,指针值被压入在堆栈上。

标签: c pointers assembly x86 att


【解决方案1】:

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

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

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

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

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

【讨论】:

    【解决方案2】:

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

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

    OTOH,y 是一个 int,因此只需 movl 12(%ebp), %ecx 即可获得它,并且不需要进一步的动作。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-20
      • 2011-10-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多