Intel Mac のコンパイラ
河野真治 @ 琉球大学情報工学です。
Mac OS X の gcc コンパイラのアセンブラ出力を眺めていたんです
が...
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が流行ってしまったのか。
---
Shinji KONO @ Information Engineering, University of the Ryukyus
河野真治 @ 琉球大学工学部情報工学科
Fnews-brouse 1.9(20180406) -- by Mizuno, MWE <mwe@ccsf.jp>
GnuPG Key ID = ECC8A735
GnuPG Key fingerprint = 9BE6 B9E9 55A5 A499 CD51 946E 9BDC 7870 ECC8 A735