29

我正在阅读一些代码,但不确定这一行的作用:

movq (%rsp), %rsp
4

2 回答 2

37

movq(假设您在谈论 x86)是四字(64 位值)的移动。这个特定的指令:

movq (%rsp), %rsp

看起来非常像将遍历堆栈帧的代码。这条特定指令获取当前堆栈指针指向的四字,并将其加载到堆栈指针中,并覆盖它。

举例来说,这个代码序列(基于真实代码,并且在英特尔而不是 AT&T 格式)将不断地从其内容加载堆栈指针,直到超出它的 16 个字节的值是 0。

576  cmpq    [rsp+0x10],0x0
582  jz      594
588  movq    rsp,[rsp]
592  jmp     576
594  ...

它可能不是堆栈帧遍历代码,但它很不寻常,因为它会替代堆栈指针以获得它通常不用于的东西。

寻常的是,向上移动堆栈帧通常涉及堆栈指针和基指针,但这通常只是向上一级(即,从函数返回)。

对于上面显示的想要向上移动多个级别的代码,使用堆栈指针可能会更快,直到到达需要的位置,然后弹出基指针(调用约定通常会推动当前基数)更改之前的指针,以便简单的弹出将恢复旧值)。

于 2010-10-04T04:53:38.667 回答
18

它是一个 64 位值的 mov。它是 64 位,因为 movq 中的“q”是四边形,而四边形是 64 位。

可以有其他示例,例如 movl,其中 l 是 32 位。

但在 movq (%rsp) 的情况下,%rsp 使用 ATT 语法..

movq (%rsp), %rsp -> movq 称为操作码,(%rsp) 称为源或 src,%rsp 称为目标或 dst。

它所做的是它在寄存器 %rsp 中查找它的值并进入该值的内存[括号“()”表示进入内存值],然后将其分配给 %rsp。

虽然两者都是相同的寄存器,但不同之处在于 %rsp 的值发生了变化。

EG:假设 %rsp 的值为 22。但 %rsp 的内存是 30。

使用这条指令 movq (%rsp), %rsp

%rsp 的新值是 30。再次因为 (%rsp) 获取 %rsp 的值,假设为 22,然后 (%rsp) 转到内存值 30,然后将其分配给目标上的 %rsp,即%rsp 本身。

于 2014-06-04T00:26:00.353 回答