2017-04-26 69 views
0

如果我提出從32位寄存器中的值說:32位和64位值共享相同的寄存器空間嗎?

movq %rdx,%rax 
    movl %edx,%eax 

將存儲在%rax中的價值得到打一頓?

+0

是的問題,但不是你想的原因。你也可以試試它。 – Jester

+0

當然可以。無論您是使用8/16/32/64位模式尋址,它都是相同的寄存器。這是一個很好的圖表:http://stackoverflow.com/a/228367/14955 – Thilo

+0

@Jester「不是你想的原因。」請詳細說明。 – Thilo

回答

2

是,

您的代碼:

mov rax,rdx 
mov eax,edx 

將執行以下操作。

rax <= rdx 
high 32 bits of rax <= 0, low 32 bits of rax <= edx. 

分配32位寄存器將使該寄存器的較高部分爲零。

與此相反的:

mov rax,rdx : rax <= rdx 
mov ax,dx  : High 48 bits of rax is unchanged!, low 16 bits of rax <= dx 

這同樣適用於字節寄存器。

32位爲64位寄存器的上半部分指定零的原因是它阻止了部分寄存器更新,這會導致指令流水線延遲。

在32或64位模式中使用16比特的碼導致延遲在以下情形:

mov rax,-1  //1 cycle 
mov ax,dx  //1 cycle 
       //stall, the values of rax-upper and ax need to be combined 
mov r8,rax  //2 cycles 

一個更好的選擇是

mov rax,-1  //1 cycle 
movzx eax,dx  //runs concurrent with previous instruction, 0 cycles 
mov r8,rax  //1 cycle 

//Total 2 cycles, twice as fast. 

此代碼是不等同於它上面的樣品,但這就是整個觀點。儘可能避免部分寄存器更新。 另請注意,由於上述原因,movzx eax,dx相當於movzx rax,dx。在x64上它縮短了一個字節,因此是首選的形式。

請注意,我沒有使用ATT的語法,原則

+0

「更好的選擇」的確速度更快,但不等同於原始的延遲代碼。 'movzx'使初始的'mov'完全多餘。另外,由於本答案前半部分給出的理由,可以更有效地將'movzx'編寫爲'movzx eax,dx'。 –