トップ «前の日記(2002-11-11) 最新 次の日記(2002-11-13)» 月表示 編集

日々の流転


2002-11-12 [長年日記]

λ. システムプログラミングSA

顔を覚えた人が見当たらなかったので今日は少々寂しかった。それにしても今度は電卓プログラムか、そろそろ添削したくなくなってきたぞー

λ. 東方紅魔郷

ハードではクリア出来なかったので、ノーマルまでレベルを落としたら、今度はラスボスに敗北。シューティングはむずい。

Tags: 東方

λ. ソースコード読み会: Linuxのprocfs

ファイルシステム班が読み会をやると言うので何となく付いて行ってみる。これでLinuxのファイルシステム周りの基本的な構造は理解できた(ような気がする)。

λ. Re: 次のプログラムをi386上で実行するとどうなるか,その理由もあわせて答えよ

例えば以下のコードが生成された(cygwinで"gcc -O0"でコンパイルした場合)とすると 「addl $16,4(%ebp)」で関数のリターンアドレスを16進めてしまうことになるはず。結果としてその間にあった「exit(1);」がスキップされて、"hoge"がプリントされるのでしょう。

_test:
	pushl %ebp
	movl %esp,%ebp
	subl $1608,%esp
	addl $16,4(%ebp)
	movl %ebp,%esp
	popl %ebp
	ret
最初の3行を実行した後のスタックのイメージ
アドレス 説明
-1608(%ebp) ?(%espの指している先)
-1604(%ebp) ?
-1600(%ebp) 自動変数s4を格納する領域
0(%ebp) 古い%ebpの値が入ってる
4(%ebp) 関数のリターンアドレスが入ってる
8(%ebp) 第1引数s0を格納する領域
12(%ebp) 第2引数s1を格納する領域
16(%ebp) 第3引数s2を格納する領域
20(%ebp) 第4引数s3を格納する領域

まぁ、コンパイラと最適化に依存するとは思うけど。 実際"gcc -O -fomit-frame-pointer"でコンパイルしたコードは以下の通りで、 これだとリターンアドレスが書き変わることもなく、普通に終了。 (exitはgcc的にはnoreturnなので、exit以降のコードが最適化で除去されてしまうというのもあるけど)

_test:
	subl $1612,%esp
	addl $16,1604(%esp)
	addl $1612,%esp
	ret
最初の1行を実行した後のスタックのイメージ
アドレス 説明
0(%esp) 自動変数s4を格納する領域
1600(%esp) ?
1604(%esp) ?
1608(%esp) ?
1612(%esp) 関数のリターンアドレスが入ってる
1616(%esp) 第1引数s0を格納する領域
1620(%esp) 第2引数s1を格納する領域
1624(%esp) 第3引数s2を格納する領域
1628(%esp) 第4引数s3を格納する領域

つーか、アセンブラって難しくて良くわからん。「?」と書いた部分は一体何に使われているのだろう。

λ. 夕食

豊田さんと、あろーむ。

λ. 帰り

に藤沢で思いがけない人物に出会う。驚きと軽い高揚。

本日のツッコミ(全2件) [ツッコミを入れる]
ψ なかだ (2002-11-13 21:46)

スタック領域のアラインメントでは。-mpreferred-stack-boundaryとか。

ψ さかい (2002-11-14 04:04)

なるほど。<br>やっぱりアラインメントだったのですか。<br><br>-mpreferred-stack-boundary=2 を指定すると、<br>確かに8バイト境界にアラインされました。<br><br># 実は、最初アラインメントかも知れないとは思ったのですが、<br># 16バイトというのはアラインメントとしては<br># 大きすぎるんじゃないかと思ってしまっていました。