2016-10-09 5 views
0

私はいくつかの操作を通して、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 
$ _ 
+1

SYSCALLはr11を破壊します。あなたは他のほとんどの登録簿を選ぶことができました。しかし、(ABI標準呼び出し規約のように)レジスタ内の関数引数を渡すか、 'mov ...、[rsp + 8]'でスタックを読み込むほうがはるかに簡単です。 FASMの 'pop rdx rsi rdi'構文は構文的な砂糖だけであり、それでも3つの命令にアセンブルされます。これは効率的ではありません。 –

+0

デバッガを使用していれば、レジスタ値をチェックできました。 –

+0

あなたは私を冗談にしなければなりません。さて、 'r12'が働いた。ちょうど私の運。どうもありがとうございました。 – qrpnxz

答えて

1

syscall命令はsyscallを行った後、あなたはR11に格納された値が上書きされることを意味RFLAGSレジスタ、とR11の内容を切り詰め。

解決策は、システムコールによって変更されていない適切なレジスタを選択することです。インテルの命令リファレンスマニュアル(http://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-manual-325462.pdf、ページ4-668 Vol.2B)syscallは、操作の一部としてRCX,RIPR11、およびRFLAGSを上書きしますが、もちろんOSはRIPとRFLAGSを復元できます。

これには他にもたくさんのオプションがあります。関数呼び出しが標準のユーザー空間呼び出し規約で壊れることが許されているが、Linuxシステムコールは変更されないままにするレジスタが良い選択です。 R8が請求書に適合します。標準x86-64 System V function-calling conventionを使用していないので、RBXまたはRBPがより良い選択肢になります(REX接頭語は必要ないため、マシンコードサイズが小さくなります)。

+0

'syscall'命令は、' RCX'を使ってシステムコールからの戻りアドレスを保存するように見えます。 – SevenStarConstellation

+0

/facepalm、もちろんそうです。私の間違い。私は、3オペランドシステムコールのために無料のコールクローバの低い8レジスタはないと思います。 (RBXとRBPはコール保存されています)。もちろん、最善の選択肢は、最初に戻りアドレスをポップしないことです。 –

+0

R8は[x86-64 SystemV ABI]で呼び出されません(http://stackoverflow.com/documentation/x86/3261/calling-conventions/11197/64-bit-system-v#t)。 = 201610092111176889144)。 RSPやRFLAGSを保存/復元する必要はありません。 FLAGSを保存するのは、SYSCALLがR11 forを使用するためです(したがって、OSの設定に関係なく、割り込みを無効にしてカーネルに入るためにマスクすることができます)。 RCXとR11の元の値は破壊されますが、それ以外のものはどこかにあり、カーネルの[SYSRET命令](http://www.felixcloutier.com/x86/SYSRET.html)の前またはその前に復元されます。 –

関連する問題