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