はりぼて日記
10月 10 (水曜日) 2007 | ||
20:50
|
22日目2
|
|
------------約1時間後-----------------
・・・あーー! なるほどなるほど! そういうことかぁ! P439の_asm_hrb_api。ここを見てみてやっとわかった! 例えばだけど、現在のスタックの番地(ESPの値)が仮に0x1234だと過程する。この状態でPUSHADを二回行うと・・・
こういう状態の後、C言語であるhrb_apiに渡される。 関数hrb_apiは各引数を、順にESP+4の倍数としてスタックから受け取る。つまり、0x11F8から int ediを、0x11FBから int esiを・・・・0x1214から int eaxを。こうして受け取っている。 ・・・ここで、
という命令を行うと、ポインタである*regには引数である int eaxのお隣、すなわち0x1218が設定される。 (*regをint型で宣言しているため、4バイト刻みになる。なので、+1するということは4バイト先ということになる) hrb_apiの後ろのほうで、
という処理をしている。これは配列という意味ではなく、*regから7個お隣と言う意味として使われている。 すなわち、0x1234番地にshtの値が書き込まれたわけである。 この処理の後、hrb_apiはreturn命令で戻る。どこへ戻るのかといえば、自分を呼び出したasm_hrb_api(アセンブラプログラム)に戻ってゆく。 処理が戻ってきたasm_hrb_apiはアプリ終了かそうでないかを判断した後、
という処理をする。これはどういうことかというと、 本来ならPOPADを二回行うはずである。(だってPUSHADを二回やってるから。そうしないとつじつまが合わない) しかし、当たり前だがPOPADはレジスタの値を書き換える。二回目にPUSHADした値はC言語実行の後だし意味がない。まるごと戻す必要がないのだ。 そこで、POPADはするがレジスタは書き換えない。そのため、ADD ESP,32を行う。これで、ESPの値すなわちスタックの番地が0x11F8から0x1228になる。 この状態でPOPAD! レジスタには、0x1228〜0x1234の値が書き込まれ、元の状態に戻る。 (ただし、本当に元の状態ではない。0x1234の値は書き換えられている。) これでIRETDを行い、処理を割り込み前のapi_openwinに戻す! アセンブラプログラムであるapi_openwinは後処理をし、呼び出し元に戻る。 api_openwinを呼び出したのはC言語であるwinhelo.cである。 処理が終わると変数winに現在のEAXの値を代入して処理を終える。 ・・・・ぷっはあぁぁぁぁ! やっとこさ整理できたーー! ・・・うーむ。ここいらへんはアセンブラやCを行ったり来たりなのでややこしいなぁ〜・・・ |
||
(1) 2 3 4 5 6 7 8 9 10 »  |
PopnupBlog V3 Denali created by Bluemoon inc. |