自作エミュレータで学ぶx86アーキテクチャ 3.7 call_rel32,ret
call-rel32とretはcall命令とret命令に対応した関数です。
(define (call-rel32 emu) (let1 diff (get-sign-code32 emu 1) (push32 emu (+ (ref emu 'eip) 5)) (eip-add emu (+ diff 5)))) (define (ret emu) (set! (ref emu 'eip) (pop32 emu)))
call-rel32はcallの次の命令の番地を基準にして前後32ビットの範囲でジャンプできる
命令です。
例えば、以下のようなプログラムだと
call hoge mov eax,0x0000
「mov eax,0x0000」がある番地を基準にして前後32ビットの範囲でジャンプできます。
call-rel32の以下の部分で
(eip-add emu (+ diff 5))))
5を足しているのは、call命令の全体が5バイトだからです。
例えば上の「call hoge」のある番地に5を足すと、基準になる「mov eax,0x0000」の
番地になります。
(push32 emu (+ (ref emu 'eip) 5))
この部分はcall命令を実行した後に戻ってくる番地をプッシュしています。
ここで5を足しているのも上の理由とだいたい同じです。
retでは、ここでプッシュした値をポップしてeipに設定しています。
(set! (ref emu 'eip) (pop32 emu)))
プログラムの全体はgithubに置いています。
https://github.com/mas454/x86emu