Is mov %esi, %esi a no-op or not on x86-64?

匿名 (未验证) 提交于 2019-12-03 02:20:02

问题:

I am a bit confused by the comment in one of the header files for the Linux kernel, arch/x86/include/asm/nops.h. It states that

<...> the following instructions are NOT nops in 64-bit mode, for 64-bit mode use K8 or P6 nops instead
movl %esi,%esi
leal 0x00(%esi),%esi
<...>

I guess the author implied the machine instructions ('89 F6' and '8D 76 00', respectively) there rather than assembly instructions. It follows from the description of LEA in Intel Software Developer's Manual Vol 2A that the latter instruction (lea 0x00(%rsi), %esi) does the same as the the former, mov %esi,%esi.

So this reduces to the question, whether mov %esi,%esi is actually a no-op on x86-64.

mov does not change flags. This kind of mov does not change memory either. It seems, if it changes something besides %rip, that should be general purpose registers. But I have no clue how it can change the contents of %rsi or whatever. If you manipulate the lower half of a general purpose register, the upper half should not change, right?

回答1:

mov %esi, %esi 

zeros out the high 32 bits of %rsi, and is therefore not a no-op on x86_64.



回答2:

#include <stdio.h>  int main(int argc, char * argv[]) {     void * reg_rsi = 0;      asm (         "movq $0x1234567812345678, %%rsi;\n"         "movl %%esi, %%esi;\n"         "movq %%rsi, %0;\n"         : "=r" (reg_rsi)         : /* no inputs */         : /* no clobbered */     );      printf("reg_rsi = %p\n", reg_rsi);      return 0; } 

This gives "reg_rsi = 0x12345678" for my x86_64 machine.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!