Eug*_*ene 8 assembly x86-64 linux-kernel
我对Linux内核的一个头文件(arch/x86/include/asm/nops.h)中的注释感到有些困惑.它说明了这一点
<...>以下指令在64位模式下不是nops,对于64位模式,使用K8或P6 nops而不是
movl%esi,%esi
leal 0x00(%esi),%esi
<...>
我想作者暗示机器指令(分别是'89 F6'和'8D 76 00')而不是汇编指令.根据LEA英特尔软件开发人员手册第2A卷中的描述,后一条指令(lea 0x00(%rsi), %esi)与前者相同,mov %esi,%esi.
所以这简化了问题,是否mov %esi,%esi实际上是x86-64上的无操作.
mov不会改变旗帜.这种mov也不会改变记忆.似乎,如果它改变了一些东西%rip,那应该是通用寄存器.但我不知道它如何改变内容%rsi或其他内容.如果你操纵通用寄存器的下半部分,上半部分不应该改变,对吧?
Ste*_*non 18
mov %esi, %esi
Run Code Online (Sandbox Code Playgroud)
将%rsi的高32位归零,因此不是x86_64上的无操作.
#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;
}
Run Code Online (Sandbox Code Playgroud)
这为我的x86_64机器提供了"reg_rsi = 0x12345678".