Sunday, 8 October 2006
Intel Mac のコンパイラ
しばらくアセンブラ出力を眺めて、やっぱり書くことを決意したのはいいんだけど...
Relocatable つまり、コードの位置をリンク時に決めない方式なので、サブルーチンの先頭に、自分のコードの位置を知るために、
0x19d9c <__i686.get_pc_thunk.bx>: mov (%esp),%ebx
0x19d9f <__i686.get_pc_thunk.bx+3>: ret
とかいうのを呼んでいる。もちろん、メモリ上の固定数値も呼ばず、大域変数にもアクセスしなければ、呼ぶ必要はないわけだけど。しかも、この位置を記憶するEBXレジスタは、ずーっと、潰れることになる。
で、大域変数は、
leal L_uc1$non_lazy_ptr-"L00000000006$pb"(%ebx), %eax
movl (%eax), %eax
movb $-56, (%eax)
でアクセスすることになる。だから、一旦ポインタに入れないと大域変数にアクセスできない。
movl L_uc1$non_lazy_ptr-"L00000000006$pb"(%ebx), %eax
movb $-56, (%eax)
これでもいいのか。
ってことは、大域変数にアクセスする時は、6個しかないia32の汎用レジスタのうち2つは、必ず、潰れているってことだね。ま、いいんだけど。ia32 には、わり算するときにはEDXがつぶれるという楽しい技もあるんだよな。 32個レジスタあるってならともかく。
なんか、昔の MC6800 を使ったアセンブラプログラミングみたい。MC6800はポインタ一つ、アキュームレータ一つだったから。これで、そこそこ速く動くCPUだってのが奇跡だ... 仮想レジスタの威力なのかなぁ。get_pc_thunk.bx みたいなので、実メモリにアクセスしていたんじゃだめだめそうなものなんだが。
もちろん、大域最適化をすれば、このあたりはだいぶましにはなるんだけど。あぁ、たくさん文字列定数を使うときには、先にまとめて、取得して局所変数に入れておくみたいなことするのかぁ。
leal LC143-"L00000000027$pb"(%ebx), %edi
movl %edi, -660(%ebp)
leal LC144-"L00000000027$pb"(%ebx), %eax
movl %eax, -664(%ebp)
leal LC145-"L00000000027$pb"(%ebx), %edi
movl %edi, -668(%ebp)
leal LC146-"L00000000027$pb"(%ebx), %eax
movl %eax, -672(%ebp)
leal LC147-"L00000000027$pb"(%ebx), %edi
movl %edi, -676(%ebp)
leal LC148-"L00000000027$pb"(%ebx), %eax
movl %eax, -680(%ebp)
なにやってるのかと思ったよ... その方がEBXが空くから有利ってことなんだろうな。大域最適化の結果がこれかよ。
なんで、こんなCPUが流行ってしまったのか。
Intel Mac のコンパイラのfixが、予想外に早く終ることを期待します。
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment