MOV% ESI,% ESI не работает или нет на x86-64? - PullRequest
8 голосов
/ 11 июля 2011

Меня немного смущает комментарий в одном из файлов заголовков для ядра Linux, arch / x86 / include / asm / nops.h .В нем говорится, что

<...> следующие инструкции НЕ являются nops в 64-битном режиме, для 64-битного режима вместо этого используйте K8 или P6 nops
movl% esi,% esi
leal 0x00 (% esi),% esi
<...>

Полагаю, автор подразумевал машинные инструкции ('89 F6 'и' 8D 76 00 'соответственно)там, а не инструкции по сборке.Из описания LEA в Руководстве разработчика программного обеспечения Intel, том 2А, последняя инструкция (lea 0x00(%rsi), %esi) делает то же самое, что и первая, mov %esi,%esi.

Так что это сводится к вопросу,* действительно ли mov %esi,%esi не используется в x86-64.

mov не изменяет флаги.Этот тип mov также не меняет память.Кажется, если что-то изменится, кроме %rip, это должны быть регистры общего назначения.Но я понятия не имею, как он может изменить содержимое %rsi или что-то еще.Если вы манипулируете нижней половиной регистра общего назначения, верхняя половина не должна меняться, верно?

Ответы [ 2 ]

18 голосов
/ 11 июля 2011
mov %esi, %esi

обнуляет старшие 32 бита% rsi и, следовательно, не является запретным для x86_64.

6 голосов
/ 12 июля 2011
#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.

...