Является ли mov %esi, %esi no-op или нет на x86-64?
Я немного смущен комментарием в одном из заголовочных файлов для ядра Linux,arch/x86/include/asm / nops.h. В нем говорится, что
следующие инструкции не являются nops в 64-разрядном режиме, для 64-разрядного режима используйте K8 или P6 nops вместо
мовл %Эси%Эси
leal 0x00 (%esi),%esi
Я думаю, что автор подразумевал машинные инструкции ('89 F6 'и' 8D 76 00 ' соответственно) там скорее чем инструкции по сборке. Это следует из описания LEA
в руководстве разработчика программного обеспечения Intel Vol 2A, что последняя инструкция (lea 0x00(%rsi), %esi
) делает то же самое, что и первый,mov %esi,%esi
.
так что это сводится к вопросу, является ли mov %esi,%esi
на самом деле нет-op на x86-64.
mov
не меняет флаги. Такого рода mov
не изменяет память тоже. Кажется, если он меняет что-то кроме %rip
, это должны быть регистры общего назначения. Но Я понятия не имею, как он может изменить содержание %rsi
или что-то еще. Если вы манипулируете нижней половиной регистра общего назначения, верхняя половина не должна меняться, верно?
2 ответов
#include <stdio.h>
int main(int argc, char * argv[])
{
void * reg_rsi = 0;
asm (
"movq x1234567812345678, %%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;
}
Это дает "reg_rsi = 0x12345678" для моей машины x86_64.