printfを呼び出すサブルーチンをいくつか定義しようとしています。次のように 非常に簡単な例である:アセンブリサブルーチンは、メインから呼び出されなくても2回呼び出されます。
extern printf
LINUX equ 80H
EXIT equ 60
section .data
intfmt: db "%ld", 10, 0
segment .text
global main
main:
call os_return ; return to operating system
os_return:
mov rax, EXIT ; Linux system call 60 i.e. exit()
mov rdi, 0 ; Error code 0 i.e. no errors
int LINUX ; Interrupt Linux kernel
test:
push rdi
push rsi
mov rsi, 10
mov rdi, intfmt
xor rax, rax
call printf
pop rdi
pop rsi
ret
ここで試験がちょうど画面に数10を出力printf関数への呼び出しを有します。私はそれが呼び出されないので、これが呼び出されるとは思わないでしょう。
はしかし、コンパイルし、実行している場合:
nasm -f elf64 test.asm
gcc -m64 -o test test.o
を私は出力を得る:
10
10
を私は完全に困惑だし、なぜこれが起こっている、誰かが説明できるのか疑問に思っ?
感謝を! printfを呼び出すのと同じように、値60(EXIT)をrdiの代わりにraxの代わりに入れますか? –
いいえ、 'rax'のシステムコール番号と' rdi'の最初の引数は正しいです。カーネルのsyscall ABIに関するいくつかのドキュメントと、ユーザーレベルの呼び出し規約との相違点については、http://www.x86-64.org/documentation/abi.pdf(特に付録A)を参照してください。 –
残念なことに残念に思っていますが、私は回線を "int LINUX"に変更してシステムコールを呼び出し、外部システムコールをトップに追加して2つの10を取得しました。あなたが私に電話をかけるためのミニ・サンプルを見せてもらえますか?どうもありがとうございます:) –