徒然ネル

LinuxカーネルとかeBPFとか

itmediaの「main()関数の前には何があるのか」を読んでみる(第一回)

itmediaの「main()関数の前には何があるのか」の連載を読んでわからなかったことや、調べたことをメモする

 

第一回は"「Hello World!」の中身を探る意義と環境構築、main(C言語)のアセンブラコードの読み方"

 

4ページ目の

「*(int *)((char *)EBP+0xc)」

が、なんでcharでキャストしてるのかわからん

→1 byteずつ明示的にアドレスを加算するためだと思われる(追記)

 

4ページ目のスタックの扱いから難しい

and命令ではスタックポインタに0xFFFFFFF0を論理積でかけあわせることで、スタックポインタを16バイト境界にそろえているようだ。

ようわからんなーと思ったけど、具体的なアドレスで考えるとわかった。

16進数で下一桁を0にすることで、16バイト境界に合わせてスタックのアドレスを下の方に移動(ゼロアドレスに向かって移動)させてるのね。

 

自動変数がなにか知らんかったけど、main関数内のローカル変数のことらしい。

 

push命令周りの話は以下の記事の解説がわかりやすそう

第六話:EBPとESP、スタック領域の使われ方|トリコロールな猫 (note.com)

 

スタックの絵を書いて、アドレスがどこを指してるのか追っていかないとわからんな。

 

あと、x86アーキテクチャレジスタ名について参照しながらじゃないとわからんくなる。

x86レジスタ 備忘録 #CTF - Qiitaより

 

関数からのリターンで、

 x86アーキテクチャでは、関数からの戻り値はEAXレジスタで返される。つまりこれはmain()関数の終端にある「return 0」の戻り値を準備していることになる。

と書いてあるけど、関数からの戻り値が0以外の場合どうなるんだ?

 

関数の先頭は16バイトや32バイトなどのキャッシュラインにアラインメントされていたほうがキャッシュ効率が良くなり、高速性が高まる。

これもわかんねー

キャッシュラインにアラインメントがわからん。

 

 

次、読み返す際に、やること。