私はいくつかの操作を通して、ret
opの問題に絞っています。私はcall
が戻りアドレスをスタックにプッシュすることを知っています。それをポップアップして戻すのは違法ですか?私は `ret 'するとセグメンテーションを取得するのはなぜですか? (FASM)
format ELF64 executable 3
entry start
segment readable executable
start:
pop rcx ; argc
mov [argc],cl ; int -> ASCII
add [argc],'0'
push 1 argc 1
call sys_write
mov rdi,0
mov rax,60
syscall
sys_write: ; (fd,*buf,count)
pop r11
pop rdx rsi rdi
mov rax,1
syscall
push r11
ret
segment readable writable
argc rb 1
出力は次のとおりです。
$ ./prog
1Segmentation fault
$ _
SYSCALLはr11を破壊します。あなたは他のほとんどの登録簿を選ぶことができました。しかし、(ABI標準呼び出し規約のように)レジスタ内の関数引数を渡すか、 'mov ...、[rsp + 8]'でスタックを読み込むほうがはるかに簡単です。 FASMの 'pop rdx rsi rdi'構文は構文的な砂糖だけであり、それでも3つの命令にアセンブルされます。これは効率的ではありません。 –
デバッガを使用していれば、レジスタ値をチェックできました。 –
あなたは私を冗談にしなければなりません。さて、 'r12'が働いた。ちょうど私の運。どうもありがとうございました。 – qrpnxz