【问题标题】:Difference between addq and movl, then addqaddq和movl的区别,然后addq
【发布时间】:2016-10-20 05:23:28
【问题描述】:

两者的功能区别是什么

addq (%rbx), %rax

movl (%rbx), %ecx addq %rcx, %rax

在组装中?

我认为他们做同样的事情,但功能上的区别是什么?

【问题讨论】:

  • 第二个例子改变了ECX,第一个没有。

标签: assembly x86-64


【解决方案1】:

第一个从rbx 位置的内存中取出一个完整 四字(64 位)并将其添加到rax 寄存器中。

第二个从同一位置提取一个 longword(仅 32 位)并将其存储到 ecx(将 rcx 的上半部分归零)。然后它将rcx 添加到rax

所以我想说主要区别在于第二个 sn-p 不是将内存中的完整四字添加到 rax,而只是添加长字。

第一个(单行)代码示例更类似于:

movq    (%rbx), %rcx
addq    %rcx,   %rax

尽管 that 并不完全相同,因为它改变了rcx。为了使其更加匹配,您可以在此过程中保存和恢复rcx

push    %rcx
movq    (%rbx), %rcx
addq    %rcx,   %rax
pop     %rcx

尽管如此,当然,您已经更改了 rsp(尽管是暂时的)并且它需要您实际设置一个堆栈(可能,但不是绝对这种情况),因此您可以最好只坚持单线:-)

【讨论】:

  • 如果您在 GNU C inline-asm 中执行此操作,push/pop 将破坏 red-zone,并且无法告诉编译器您想要这样做。因此,只需使用单行代码并告诉编译器有关寄存器破坏的信息,而不是自己保存/恢复!
  • @Peter,你可能是对的,我没有研究过这方面,主要是因为 OP 没有提到在 C 中使用 asm 关键字 - 我假设,基于问题和标签,这是纯粹的组装。
  • 对,我也是这么想的。但作为对其他情况的一般建议,它是相关的。也许您正在编写一个汇编器宏:破坏红色区域对宏来说是一个令人讨厌的副作用,并且比破坏寄存器更难调试。如果需要,最好将 tmp 寄存器作为宏参数。
猜你喜欢
  • 1970-01-01
  • 2020-02-18
  • 2012-11-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-26
相关资源
最近更新 更多