2011-12-07 31 views
3

從我所瞭解的英特爾手冊中,應該可以編寫一個像「add $ 0x7f,%ebx」這樣的指令,它應該被編碼爲83/0 ib,總共三個字節。但是,當我這樣做時(無論我使用「add」,「addb」還是「addl」),它總是將立即值提升爲32位值,並編碼爲81/0 ID並佔用6個字節。 adc,sub等存在同樣的問題。請注意,我正在使用帶有GNU as的AT & T語法。如何在x86上使用AT&T語法將一個立即字節添加到長寄存器?

我一直在尋找解決方案超過一天,並沒有找到它。任何人都可以請指教?

回答

2

令人驚訝的是,我沒有這樣的問題。

我把通過gcc(DJGPP)生成此彙編代碼:

 .file "im.c" 
.globl _x 
     .section  .bss 
     .p2align 2 
_x: 
     .space 4 
     .section .text 
     .p2align 4,,15 
.globl _main 
_main: 
     pushl %ebp 
     movl %esp, %ebp 
     pushl %eax 
     pushl %eax 
     movl _x, %eax 
     andl $-16, %esp 
     addl $127, %eax 
     movl %eax, _x 
     movl %ebp, %esp 
     xorl %eax, %eax 
     popl %ebp 
     ret 
     .ident "GCC: (GNU) 3.3.4" 

並編譯它as,這是我所看到的a.out中:

55    push ebp 
89E5    mov ebp,esp 
50    push eax 
50    push eax 
A100000000  mov eax,[0x0] 
83E4F0   and esp,byte -0x10 
83C07F   add eax,byte +0x7f 
A300000000  mov [0x0],eax 
89EC    mov esp,ebp 
31C0    xor eax,eax 
5D    pop ebp 
C3    ret 

而C程序是:

volatile int x = 0; 

int main(void) 
{ 
    x += 0x7F; 
    return 0; 
} 

你確定你的直接操作數可以以8位有符號整數表示?如果超出了-128到+127的範圍,彙編器將不得不使用更長的編碼。

+0

很奇怪。我在eax,ebc,ecx和edx中發出了立即值的所有256個變體,並且還使用了每個助記符後綴(b,w和l),並且沒有得到單個83編碼;他們都出來了81.我正在裝配最新的穩定的Ubuntu。我提到的其他指令也存在類似的問題。 :/ – user1084743

+0

我剛剛根據您對負值的評論進行了重新測試。當我將自己限制在0-127的範圍內時,我可以得到預期的結果。謝謝。 – user1084743

+0

@ user1084743:啊,這就是問題所在。 CPU文檔說,即時字節被視爲有符號並在ALU操作中使用之前獲得符號擴展。所以,即使您認爲+128或+255只需要1個字節,對於無符號字節來說也是如此。 –

相關問題