先週はさまざまなCPUのレジスタアーキテクチャ(Register architecture) について学んだ。
例えば Intel 386 ならば、
例えば、
negl %eax レジスタEAXのnegativeを取る negl a 大域変数aのnegative を取る negl (%eax) レジスタEAXの指すメモリのnegativeを取る negl (%ebx+%eax) EAX+EBXの指すメモリのnegativeを取る間接参照には、さらにオフセットを付けることができる
negl 4(%eax) レジスタEAXの指すメモリから4byteずれたところのnegativeを取る negl 4(%ebx+%eax) EAX+EBXの指すメモリから4byteずれたところのnegativeを取る
i386はlittle-endianであり、メモリにはメモリのアドレス が小さい方に、 数値の小さい桁から格納される。また、%eaxレジスタは、 高い方の桁が8bit %ahレジスタ、低い方の桁が8bit レジスタ%alとなっている。 以下の数値は16進表記とする。
メモリの内容が以下のようになっているとき、
0000100: 23 0000101: 45 0000102: 56 0000103: 78 0000104: 90 0000105: 12
BSD/OS の gdb の man ページには、ほとんどなんの記述もない。その 代わりに、info ページが充実している。mule の info か、または、 info コマンドを用いて、GDB の情報を調べてみよ。
gdb には、i386 のレジスタ一覧を表示する機能はない。gdb のaliases 機能を用いて、gdb にその機能を追加するには、
define regs printf "%%eip=%08x: %%eax=%08x %%ebx=%08x %%ecx=%08x %%edx=%08x %%edi=%08x %%esi=%08x %%ebp=%08x %%esp=%08x\n", $eip,$eax,$ebx,$ecx,$edx,$edi,$esi,$ebp,$esp endを.gdbinitに追加する。
stepi disass $eip $eip+1は何をするコマンドが調べよ。
アセンブラのシングルステップが便利になるようなaliasを定義してみよ。
i386では、基本的に演算は、register to register で行われる。 ここでは、以下のプログラムを使おう。
int a=4,b=3; main() { a = a+1-(b-123); return a; }これを gcc -S でコンパイルしてみると、 .s というファイルに以下の内容がかかれる。(コメントはでないが...)
.file "tmp.c" .version "01.01" gcc2_compiled.: .globl a .data .align 4 .type a,@object .size a,4 a: .long 4 .globl b .align 4 .type b,@object .size b,4 b: .long 3 .text .align 4 .globl main .type main,@function main: pushl %ebp movl %esp,%ebp movl b,%eax # 変数bの値を %eax にロードする addl $-124,%eax # -124 を %eax に加算する movl a,%edx # 変数aの値を %edx にロードする subl %eax,%edx # %edx から %eax の内容を引く movl %edx,%eax # %edx の内容を %eax に移す movl %eax,a # %eax の値を変数aに格納(ストア)する leave ret .Lfe1: .size main,.Lfe1-main .ident "GCC: (GNU) 2.8.1"となる。a: などが大域変数の場所を表している。
上のプログラムをIntel CPU上で、gcc -O -S test.c を使って コンパイルすると最適化がかかる。最適化した 場合としない場合で、どのような違いが出るか? (ヒント diff を使うと 簡単...)
問1で、 これらの結果を実際のアセンブラで実行しテストするには、どうすれば良いか 考えて実行せよ。
これらの命令が実際に生成されるCのソースコードを考えて、それをコンパイラ に通し、実際に命令が生成されることを確認せよ。(ただし、データのアドレスは、 変わっても良いとする)
Subject: Report on Compiler consturction Lecture 11/1というSubjectのメールにして、kono@ie.u-ryukyu.ac.jp まで送ること。 また授業を受けなかったものは、課題を、
Subject: Practice on Compiler consturction Lecture 11/1というサブジェクトで送ること。 来週の授業(11/8, 11/15)は休講とします。