コピー2018.10.13rcs学習もそろそろ飽きてきたので、気まぐれにより、Cとアセンブラやります。C言語のプログラムの中にアセンブラを書きたい時ってたまにありますが、アセンブラってプロセッサによって変わってきますよね。プロセッサはたくさんあるので、全部のアセンブラを覚えるのって大変ですし、たまに書きたい言語をいちいち覚えたくありません。使いたいアセンブラは、ディスアセンブルしたソースを見て、その場で学習して使えば良いです。適当にC言語プログラム書いてみます。func1(10,20,30);}takk@deb9:~/tmp$func1という関数の引数に10,20,30を渡して実行すると、各値を標準出力するプログラムです。実行結果は分かり切ってますので、さっそくビルドして、ディスアセンブル。-nfunc1のアセンブラと、mainのアセンブラのみ抜粋します。nopmainからfunc1をコールする時、引数に値を設定するアセンブラは、16進数の数値から読み取るとこの部分ですね。$0xa,%edi3番目の引数から、2番目、1番目の順序でレジスタに設定されています。各レジスタ名で用途が決まっていますが、絶対そういう使い方をしないといけないってことはありません。上のプログラムでは、10,20,30という値は、sourceでもdestinationでもなく、ただのdataなので、分かりやすく書くなら、dx1,dx2,dx3みたいなレジスタ名であれば良いのですが、そんなレジスタはないので、空いてるレジスタが割り当てられています。コンパイル時にどのレジスタから使うかは優先順位が決まっているのでしょうけど、気にしないことにします。元のソースをコピーして、アセンブラを混入させるソースを作ります。t2.cディスアセンブルされたソースの、この行と同じアセンブラをC言語のソースに埋め込みたいと思います。func1(10,20,30);}takk@deb9:~/tmp$main関数の150行目でedxに0x1e、つまり30を代入してるので、func1関数の135行目のアセンブラが実行される時も、edxには30が格納されています。それをrbpの-0xcの位置に上書きするだけの処理になります。|rbp-0x4+------+実行してみます。c=30takk@deb9:~/tmp$想定通りの結果ですね。次は、30をrbpの別の場所に格納してみます。func1(10,20,30);}takk@deb9:~/tmp$埋め込んだアセンブラでは、-0x4(%rbp)を指定しているので、以下のように10が入っていたメモリには30が上書きされるはずです。|rbp-0x4+------+実行してみます。c=30takk@deb9:~/tmp$うまくいきました。テンポが良くてすごく面白いです。最終話まで継続視聴予定です。エンディアン変換のアセンブラを作っていて、気がつきました。競輪みたいに、レースでギャンブルする競技なのでしょう。女子たちがプールで尻相撲します。プールに落ちたりしたら負け。