2011-12-07 3 views
3

私はIntelのマニュアルを読んで理解しているので、 "add $ 0x7f、%ebx"のような命令を書くことが可能でなければならず、合計3バイトのために83/0 ibとしてエンコードする必要があります。しかし、私が "add"、 "addb"、または "addl"を使用するかどうかにかかわらず、これを実行すると、即値を32ビット値に "プロモート"し、81/0 idとしてエンコードし、6バイトを占有します。同じ問題がadc、subなどにもあります。私はAT &というT構文をGNUで使っています。x86のAT&T構文を使用して、長いレジスタに直接バイトを追加する方法はありますか?

私は1日以上解決策を探しており、それを見つけられませんでした。誰でも助言してもらえますか?

答えて

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

非常に奇妙です。 IはEAX、EBC、ECX、およびEDXに即値のすべての256個の変異体を射出され、また、各ニーモニックサフィックスを使用する(B、W、及びL)、および単一の83符号化を得ていません。彼らはすべて81として出てきます。私は最新の安定したUbuntuを組み立てています。私が言及した他の指示にも同様の問題が存在する。 :/ – user1084743

+0

私は、負の値に関するあなたのコメントに基づいて再テストしました。私が0-127の範囲の値に自分自身を制限すると、私は期待される結果を得ます。ありがとうございました。 – user1084743

+0

@ user1084743:ああ、それは問題です。 CPUのマニュアルによれば、即値バイトは符号付きとして扱われ、ALU演算で使用される前に符号拡張されています。したがって、+128または+255には1バイトしか必要ないように見えるかもしれませんが、それは符号なしバイトにのみ当てはまります。 –

関連する問題