2011-07-11 27 views
8

我對Linux內核的一個頭文件arch/x86/include/asm/nops.h中的評論有些困惑。它指出,是mov%esi,%esi一個no-op或不在x86-64上?

< ...>下面的指令不NOP指令在64位模式,64位模式下使用K8或P6空指令而不是
MOVL%ESI,ESI%
萊亞爾爲0x00( %ESI),%ESI
< ...>

我猜測作者暗示的機器指令('89 F6' 和 '76 8D 00',分別地)存在,而不是組裝說明。從英特爾軟件開發人員手冊卷2A中LEA的說明可以看出,後者的指令(lea 0x00(%rsi), %esi)與前者mov %esi,%esi的做法相同。

因此,這可以歸結爲這樣一個問題,即mov %esi,%esi實際上是否是x86-64上的禁用操作。

mov不改變標誌。這種mov也不會改變內存。看來,如果它改變%rip以外的東西,那應該是通用寄存器。但我不知道它如何改變%rsi或其他什麼的內容。如果操縱通用寄存器的下半部分,上半部分不應該改變,對吧?

回答

15
mov %esi, %esi 

將%rsi的高32位清零,因此在x86_64上不是無操作。

+3

作爲一個裝配員看待,這是你的第486個答案,這是否意味着你現在不再回答問題了? (對不起,蹩腳的486笑話......我記得我的486DX2 ......現在我完全脫離了主題) – Steve

+2

只是添加到答案中,英特爾開發手冊的相關部分是3.4.1.1(在第1卷中) 。 –

+4

@Steve:我寫的程序集的第一個平臺是68k,所以我想我有一段時間才能把它掛起來...... –

6
#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; 
} 

這給我的x86_64機器「reg_rsi = 0x12345678」。

+1

你是對的,這同樣適用於'rax'和'eax'。不過:將'movl'換成'xor',它將把整個64位清零。 – Orwellophile