我正在阅读一些代码,但不确定这一行的作用:
movq (%rsp), %rsp
movq
(假设您正在谈论 x86)是四字(64 位值)的移动。这个特殊的指令:
movq (%rsp), %rsp
看起来非常像将遍历栈帧的代码。这条特殊的指令获取当前堆栈指针指向的四字,并将其加载到堆栈指针中,覆盖它。
举例来说,此代码序列(基于真实代码,采用 Intel 而不是 AT&T 格式)将不断从其内容加载堆栈指针,直到超出它的 16 个字节的值为 0。
576 cmpq [rsp+0x10],0x0
582 jz 594
588 movq rsp,[rsp]
592 jmp 576
594 ...
它可能不是堆栈框架遍历代码,但它是不寻常的,因为它会将堆栈指针用于它通常不用于的东西。
不寻常之处在于向上移动堆栈帧通常涉及堆栈指针和基指针,但这通常只是为了上升一个级别(即从函数返回)。
对于上面显示的那种你想要向上移动多个级别的代码,使用堆栈指针可能会更快,直到你到达你需要的位置,然后弹出基指针(调用约定通常会推动当前更改它之前的基指针,以便简单的 pop 将恢复旧值)。
它是一个 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
本身。