webdevqa.jp.net

x86アセンブリpushl / poplが「エラー:サフィックスまたはオペランドが無効です」で機能しない

私は、アセンブリプログラミングの初心者です。GNUアセンブラv2.20.1を使用して、Ubuntu x86_64デスクトップで Programming Ground Up を使用して作業しています。

スタックを操作するためにpushl/popl命令を使用するまで、コードをアセンブル/リンク実行できました。次のコードはアセンブルに失敗します:

 .section .data  # empty

 .section .text
.globl _start
_start:
 pushl $1       # Push the value 1 onto the stack
 popl %eax      # pop 1 off the stack and into the %eax register
 int $0x80      # exit the program with exit code '1'

「test.s -o test.oとして」を使用すると、これらのエラーが端末に表示され、test.oは作成されません。

test.s: Assembler messages: 
test.s:9: Error: suffix or operands invalid for 'Push'
test.s:10:  Error: suffix or operands invalid for 'popl'

ドキュメントを確認しましたが、pushlとpoplに使用しているオペランドは有効です。これは正確にデバッグの質問ではありません-それで私のコードの何が問題になっていますか?それとも私のアセンブラですか?

28
maxm

64ビットモードでは、32ビット値をプッシュおよびポップできません。 pushqpopqが必要です。

また、この方法では適切な出口が得られません。 32ビットx86では、exit()システムコールを選択するために_%eax_を1に設定する必要がありますand _%ebx_を実際に必要な終了コードに設定します。 64ビットx86(これが使用しているもの)では、規則が異なります。exit()のシステムコール番号は1ではなく60です。最初のシステムコールパラメータは_%rdi_ではなく_%rbx_に入ります。システムコール呼び出しのオペコードは_int $0x80_ではなく、特別なx86-64のみのオペコードsyscallです。

につながる:

_.section .data
.section .text
.globl _start
_start:
    pushq   $60
    popq    %rax
    pushq   $1
    popq    %rdi
    syscall
_

(各Push/popシーケンスは、単純なmov(_mov $60, %eax_のような)に置き換えることができます。もちろん、明示的にテストしようとしていると思いますPushpop、コードサイズを最適化、またはマシンコードで_0_バイトを回避(エクスプロイトペイロードの場合))


関連:

31
Thomas Pornin

私も最近これらの例に従っています。

  1. アセンブリコードの先頭に.code32を追加します
  2. --32フラグを使用してアセンブルする
  3. -m elf_i386フラグとリンクする

あなたは私の例を見ることができます ここ

14
agam

プッシュ/ポップシーケンスを次のものに置き換える必要があります。

pushq $1       # Push the value 1 onto the stack
popq %rax      # pop 1 off the stack and into the %eax register

エラーメッセージが「suffix or operand invalid」であることに注意してください。エラーメッセージの論理ORの2番目の部分のみをチェックしました。おそらく、サフィックスが正確にわからなかったためですつまり、「l」です。

編集:コードがアセンブルされても機能しない理由の説明については、Thomasの回答を参照してください。

7
Gunther Piez

私は同じ本で作業中にこのエラーに遭遇しました。次のシェルスクリプト(att.sh)を作成しました。

#!/bin/sh
as --32 $1.s -o $1
ld -melf_i386 $1.o -o $1
./$1
echo $?

次に、実行可能にして実行しました(入力ファイルmyfile.sを想定)。

chmod +x ./att.sh
./att.sh myfile
2
RazerSwift