課題
FF200から機械語プログラムを置きなさい。
FF800番地 - FF801番地に2バイトの値が,FF802番地 - FF803番地に2バイトの値があり,
それぞれ正の整数であるとして,この2数の積を求め,FF804番地 - FF805番地に保存するプログラム。
●元にすべきプログラムは次のものである。
Cプログラムファイル mult.c |
short int x00=0x55; short int x10=0xa; short int y0; /* x0=x00*x10 */ int main() { short int x0,x1,x2; x0=x00; x1=x10; x2=0; do { if(x1&1) x2+=x0; x0<<=1; x1>>=1; } while (x1); y0=x2; } |
x00とx01をかけてy0に答えをしまうプログラムなので,これを題意に合うように変更する方針をとる。
上記のmult.cをCプログラムをアセンブリプログラムに変換するプログラムc2asm.cmdでアセンブリプログラムに変換する。
●mult.srcとmult_1.srcが生成されるが,mult_1.srcが余計なコメント行を消したものである。
アセンブリプログラム mult_1.src |
.CPU 300HA .EXPORT _x00 .EXPORT _x10 .EXPORT _y0 .EXPORT _main .SECTION P,CODE,ALIGN=2 _main: ; function: main MOV.W @_x00:24,E0 MOV.W @_x10:24,R0 SUB.W R1,R1 L10: BTST.B #0,R0L BEQ L11:8 ADD.W E0,R1 L11: SHLL.W E0 SHAR.W R0 BNE L10:8 MOV.W R1,@_y0:24 RTS .SECTION D,DATA,ALIGN=2 _x00: ; static: x00 .DATA.W H'0055 _x10: ; static: x10 .DATA.W H'000A .SECTION B,DATA,ALIGN=2 _y0: ; static: y0 .RES.W 1 .END |
mult_1.srcで先頭のファイルの名前は不要,.EXPORTの行も(EXPORT:他のプログラムとあわせる際にこの名前が使えるように外部に見せますという意味)不要。
これらを削って,「アセンブリプログラム mult_1.src その2」を得る。
アセンブリプログラム mult_1.src その2 |
.CPU 300HA .SECTION P,CODE,ALIGN=2 _main: ; function: main MOV.W @_x00:24,E0 MOV.W @_x10:24,R0 SUB.W R1,R1 L10: BTST.B #0,R0L BEQ L11:8 ADD.W E0,R1 L11: SHLL.W E0 SHAR.W R0 BNE L10:8 MOV.W R1,@_y0:24 RTS .SECTION D,DATA,ALIGN=2 _x00: ; static: x00 .DATA.W H'0055 _x10: ; static: x10 .DATA.W H'000A .SECTION B,DATA,ALIGN=2 _y0: ; static: y0 .RES.W 1 .END |
行の左端にある「名前」+「:」はラベルであり,その次の行にあるプログラムやデータの存在アドレスを意味する。
実行プログラムの終端は「RTS(ReTurn from Subroutine)」になっている。Cプログラムではmain()が関数であるので,関数の終端としてこのようになっている。
●ここで以前作成した足し算プログラムを参考に仕上げていく。
2.(1)で使用した足し算プログラム test.src |
.CPU 300HA .SECTION A,DATA,LOCATE=H'0FF030 .DATA.L H'0FF130 ;リセットベクトル .SECTION P,CODE,LOCATE=H'0FF130 MOV.L #H'FFF00,ER7 ;スタックポインタ設定 MOV.W @data1, r0 ;data1にある値をレジスタr0へ MOV.W @data2, r1 ;data2にある値をレジスタr1へ ADD.W r1,r0 ;レジスタr0+r1→r0 MOV.W r0,@data3 ;レジスタr0にある値をdata3へ EternalLoop: BRA EternalLoop ;永久ループ .SECTION D,DATA,LOCATE=H'0FF800 data1: .DATA.W H'1234 data2: .DATA.W H'2345 data3: .DATA.W H'3456 .END |
●「2.(1)で使用した test.src」において次のことが確認できる。
・0FF130はプログラムの先頭アドレス
・プログラム本体は次の通り
MOV.W @data1, r0 ;data1にある値をレジスタr0へ
MOV.W @data2, r1 ;data2にある値をレジスタr1へ
ADD.W r1,r0 ;レジスタr0+r1→r0
MOV.W r0,@data3 ;レジスタr0にある値をdata3へ
・プログラムの終了のところはいろいろな書き方があるが,つぎの2行が終了部
(自分自身へのジャンプ)
EternalLoop:
BRA EternalLoop ;永久ループ
・プログラム中の@data1,@data2,@data3はその変数のアドレスを表していた。
・つぎの表現は,アドレス0FF800からdata1,data2,data3を2バイトずつ並べているという意味であった。
.SECTION D,DATA,LOCATE=H'0FF800
data1:
.DATA.W H'1234
data2:
.DATA.W H'2345
data3:
.DATA.W H'3456
●「2.(1)で使用した test.src」が機械語に変換されたものは「2.(4)」に載っていた。
2.(4) 機械語に変換された状態 |
FF130
7A07000FFF00
MOV.L #H'000FFF00:32,ER7 FF136 6B20000FF800 MOV.W @H'FF800:24,R0 FF13C 6B21000FF802 MOV.W @H'FF802:24,R1 FF142 0910 ADD.W R1,R0 FF144 6BA0000FF804 MOV.W R0,@H'FF804:24 FF14A 40FE BRA FF14A:8 |
FF130からプログラムが始まっていることがわかる。
@data1がFF800,@data2がFF802,@data3がFF804に変換されていることがわかる。
●「mult_1.src その2」に必要なものを書き加え,修正していく。
SECTION疑似命令のところに「LOCATE=」で,プログラムや変数のアドレスを設定することが出来る。
この課題ではプログラムの先頭がFF200なので修正,乗算の2変数はFF800,FF802に並んでいるので,先頭をFF800に設定する。
積を保存するところはFF804なので,これもFF804に設定する。
アセンブリプログラム mult_1.src その3 |
.CPU 300HA .SECTION A,DATA,LOCATE=H'0FF030 .DATA.L H'0FF200 ;リセットベクトル .SECTION P,CODE,LOCATE=H'0FF200 MOV.L #H'FFF00,ER7 ;スタックポインタ設定 _main: ; function: main MOV.W @_x00:24,E0 MOV.W @_x10:24,R0 SUB.W R1,R1 L10: BTST.B #0,R0L BEQ L11:8 ADD.W E0,R1 L11: SHLL.W E0 SHAR.W R0 BNE L10:8 MOV.W R1,@_y0:24 EternalLoop: BRA EternalLoop ;永久ループ .SECTION D,DATA,LOCATE=H'0FF800 _x00: ; static: x00 .DATA.W H'0055 _x10: ; static: x10 .DATA.W H'000A .SECTION B,DATA,LOCATE=H'0FF804 _y0: ; static: y0 .RES.W 1 .END |
「MOV.W @_x00:24,E0」の@_x00などのところは,直接アドレスを書いても良いが,上記のプログラムの方が,汎用性が保てる。
直接アドレスを書くとプログラムは短くなって次のようになるが,汎用性は失われた。
アセンブリプログラム mult_1.src その4 |
.CPU 300HA .SECTION A,DATA,LOCATE=H'0FF030 .DATA.L H'0FF200 ;リセットベクトル .SECTION P,CODE,LOCATE=H'0FF200 MOV.L #H'FFF00,ER7 ;スタックポインタ設定 _main: ; function: main MOV.W @H'FF800:24,E0 MOV.W @H'FF802:24,R0 SUB.W R1,R1 L10: BTST.B #0,R0L BEQ L11:8 ADD.W E0,R1 L11: SHLL.W E0 SHAR.W R0 BNE L10:8 MOV.W R1,@H'FF804:24 EternalLoop: BRA EternalLoop ;永久ループ .END |