我正在阅读一些代码,不确定这行代码的作用:
movq (%rsp), %rsp
k4emjkb11#
movq(假设您讨论的是x86)是一个四字(64位值)的移动。
movq
看起来很像是在堆栈帧中遍历的代码。这个特殊的指令抓取当前堆栈指针所指向的四字,并将其加载到堆栈指针中,覆盖它。举例来说,这个代码序列(基于真实的代码,并且是Intel格式而不是AT&T格式)将连续地从其内容加载堆栈指针,直到超出它16字节的值为0。
576 cmpq [rsp+0x10],0x0 582 jz 594 588 movq rsp,[rsp] 592 jmp 576 594 ...
有可能它不是堆栈帧遍历代码,但这是不寻常的,因为它会为它不常使用的东西贿赂堆栈指针。这是不寻常的,因为向上移动堆栈帧通常涉及堆栈指针和基指针,但这通常只是为了向上一级(即从函数返回)。对于上面所示的代码,如果你想向上移动多个级别,那么使用堆栈指针直到你到达你需要的位置,然后弹出基指针(调用约定通常会在改变当前的基指针之前推送它,这样一个简单的弹出就可以恢复旧的值)可能会更快。
a8jjtwal2#
它是一个64位值mov。它是64位的,因为movq中的“q”是四进制的,而四进制是64位的。可以存在其它示例,诸如movl,其中l是32位。但是在movq (%rsp), %rsp使用ATT语法的情况下。movq (%rsp), %rsp-〉movq称为操作码,(%rsp)(左操作数)称为源或src,%rsp(右操作数)称为目标或dst。它所做的是在寄存器%rsp中查找,得到它的值,并进入该值的内存[括号“()”表示进入内存值],然后将它赋给%rsp。虽然两者是相同的寄存器,但不同之处在于%rsp的值发生了变化。比方说%rsp的值是22,但是%rsp的内存是30。使用此指令movq (%rsp), %rsp%rsp的新值为30。这也是因为(%rsp)获得了%rsp的值(假定为22),然后(%rsp)转到内存值30,然后将其分配给目标上的%rsp,即%rsp本身。
mov
movl
l
(%rsp)
%rsp
2条答案
按热度按时间k4emjkb11#
movq
(假设您讨论的是x86)是一个四字(64位值)的移动。看起来很像是在堆栈帧中遍历的代码。这个特殊的指令抓取当前堆栈指针所指向的四字,并将其加载到堆栈指针中,覆盖它。
举例来说,这个代码序列(基于真实的代码,并且是Intel格式而不是AT&T格式)将连续地从其内容加载堆栈指针,直到超出它16字节的值为0。
有可能它不是堆栈帧遍历代码,但这是不寻常的,因为它会为它不常使用的东西贿赂堆栈指针。
这是不寻常的,因为向上移动堆栈帧通常涉及堆栈指针和基指针,但这通常只是为了向上一级(即从函数返回)。
对于上面所示的代码,如果你想向上移动多个级别,那么使用堆栈指针直到你到达你需要的位置,然后弹出基指针(调用约定通常会在改变当前的基指针之前推送它,这样一个简单的弹出就可以恢复旧的值)可能会更快。
a8jjtwal2#
它是一个64位值
mov
。它是64位的,因为movq
中的“q”是四进制的,而四进制是64位的。可以存在其它示例,诸如
movl
,其中l
是32位。但是在
movq (%rsp), %rsp
使用ATT语法的情况下。movq (%rsp), %rsp
-〉movq称为操作码,(%rsp)
(左操作数)称为源或src,%rsp
(右操作数)称为目标或dst。它所做的是在寄存器
%rsp
中查找,得到它的值,并进入该值的内存[括号“()”表示进入内存值],然后将它赋给%rsp
。虽然两者是相同的寄存器,但不同之处在于
%rsp
的值发生了变化。比方说
%rsp
的值是22,但是%rsp
的内存是30。使用此指令
movq (%rsp), %rsp
%rsp
的新值为30。这也是因为(%rsp)
获得了%rsp的值(假定为22),然后(%rsp)
转到内存值30,然后将其分配给目标上的%rsp
,即%rsp
本身。