6

printf関数を使った簡単なアセンブルプログラムを書いてみました。私はそれをコンパイルしnasm -f elf 64、を使用してリンクしgccます。走った後、私は見segmentation faultます。なにが問題ですか?

[Bits 32]

extern printf
global main

section .data 

hello:
db "Hello", 0xa, 0 

section .text

main:

push hello
call [printf]

add esp, 4

mov eax, 1
mov ebx, 0
int 80h
4

2 に答える 2

7

Linux on ia32は、amd64と同じ呼び出し規約を使用しません。コードは前者を使用するため、32ビットとしてアセンブルし、32ビットのlibcとリンクする必要があります。Debianでは、libc6-dev-i386パッケージが必要です。

また、「call[printf]」を「callprintf」に置き換える必要があります。これは間違いです。

また、メインインターフェイスを使用している場合は、Cランタイムシャットダウンコードを実行できるようにするために、exitシステムコールを実行する代わりにmainから戻る必要があることにも注意してください。

ビルド手順を含むx86-32のHelloWorldの例

amd64で作業している場合は、代わりに64ビットアセンブリを作成する方法を学びたいと思うかもしれません。

ビルド手順を含むx86-64のHelloWorldの例

于 2012-08-02T21:24:12.973 に答える
3

コード ヘッダーが示すように、本当に 32 ビット バイナリを取得したい場合は、次の行を修正するだけです。

call [printf]

それを次のように変更します。

call printf

call [printf]printf を呼び出すのではなく、最初の printf コード バイトが指すアドレスを呼び出す場合、その構成 ( )[address]実効アドレスと呼ばれます。

于 2012-08-02T21:55:39.400 に答える