この記事では、過去問のアセンブラの問題に載っているプログラムを実際に自分の環境で作成して動かすのに使ったコードと、トレースのノートを掲載しています。
この記事を通してアセンブラだけでなくアルゴリズムのトレース力向上にもお役立て下さい。
アセンブラ過去問プログラミング
アセンブラ自作サンプルへ
基本情報技術者試験トップへ
令和2年度(令和3年1月合格報告)
この問題は平成25年春の過去問と似ています。
この問題は、ビット列Aのある部分をビット列Bに置換するプログラムです。
具体例によると、ビット列Aの55ビット目(3語目の7ビット)から66ビット目(4語目の2ビット)までをB列に変えます。55ビット目をpとしてGR2に、B列の置換対象の12ビットをqとしてGR3に設定します。
ビット列Aの先頭アドレスはGR1に設定します。
ビット列Aの対象区間は、先頭を0ビットとして55ビットからなので、1語を16ビットとして、3語目の7ビット目~4語目の2ビット目までです。
ビット列Aの3語目、4語目を仮に「0101010101010101」
「0101010101010101」とします。
これをビット列Bである「1011000111010000」置き換えるので、ビット列Aは
操作前A:「0101010101010101」
「0101010101010101」
操作後A:「0101010101100011」
「1010010101010101」
と置換されます。
プログラムはこちらになります。
H21A_REPLACEという名前で作りました。
シミュレーターと過去問を解くまでの勉強に使った参考書はこちらです
先ほど2進数で書いた所は、全て16進数に直してプログラミングしています。
例えばビット列Aの「0101010101010101」は「#55」にしています。ビット列Aの先頭アドレスは「ARETSU」というラベルを貼りました。
そこに0語目~5語目までを格納しました。
では、動かして見ます。
シミュレーターを使って、少しくどいかもしれませんが、丁寧目にトレースしていきます。
まず、主記憶ですが、ビット列Aが入っているARETSUは、このようになっています。
先頭が#1020で、置換対象である3語目が#1023、4語目が#1024です。
レジスタはビットの状態が分かるように2進数表記にします。
GR1にビット列Aの先頭アドレスが入りました。
GR2に置換対象位置である55(0ビットを先頭として56番目)が入りました。
GR3に置換するビットの長さである12が入りました。
GR0にビット列Bが入りました。
副プログラム問題文のREPLACEを呼び出しました。
ビット位置の55をGR4に読み込みました。
55は何語目か求めるために、1語16なので55を16で割りました。
その為にSRL 4しています。55は3語目と求まりました。
(0語目、1語目、2語目、3語目)
GR1に3語先のアドレスを設定しました。
55は3語目の中で7ビット目だということが#000FとANDを取ることによって
求まりました。
GR4に、16が入りました。3語目の7ビット以降のビット数を求めるため、
16から7を減算します。
GR4に16から7を引いて、9と求まりました。
GR5にビット列Bを退避しました。
これはビット列Aの4語目の置換に使います。
GR6に置換に使うマスクを作る為に#8000が入りました。
マスクを作るのに論理シフトします。シフトするビット数を
12から1を引いて11と求まりました。
注意して頂きたいのが次に行うシフトは「算術シフト」です。
つまり、空いた所に先頭ビットと同じビットが入ります。
GR6が、#8000である「1000000000000000」を11ビット右に算術シフトして、「1111111111110000」になりました。
今作ったマスクを、GR7に退避します。
これはビット列Aの4語目の置換の作業に使うマスクになります。
GR0で、ビット列Bを右に7ビットシフトしました。
GR6で、マスクを右に7ビットシフトしました。
GR5で、4語目用にビット列Bを左に9ビット論理シフトしました。
GR7で4語目用にマスクを左に9ビットシフトしました。
GR2にビット列Aの3語目を読み込みました。
GR6「0000000111111111」にGR2の「0101010101010101」のANDを取りました。
結果は「0000000101010101」です。
GR2「0101010101010101」とGR6「0000000101010101」のXOR排他的論理和を取りました。
結果は「0101010000000000」です。
GR2に右シフトしたビット列BであるGR0「0000000101100011」を足しこみます。
結果は「0101010101100011」になります。
主記憶のビット列Aの3語目に格納されました。
GR2にビット列Aの4語目が読み込まれました。
GR7に「1110000000000000」とGR2「0101010101010101」のANDを取りました。結果は「0100000000000000」になりました。
GR2に「0101010101010101」とGR7の「0100000000000000」の排他的論理和XORを取ります。結果は「0001010101010101」になりました。
GR2に「0001010101010101」と左シフトしたビット列Bの「1010000000000000」のORを取ります。
結果は「1011010101010101」になります。
ビット列Aの4語目に格納されました。
トレースは以上になります。
今度受けるので、自分の勉強になりました。
どなたかのお役に立てたらうれしいです。
誰か見ている人いますか?いたら手を振って下さい(=^・^=)
プログラムはこちらになります。
<<プログラム>>
H21A START
RPUSH
LAD GR1,ARETSU
LD GR2,=55 ;pの位置55
LD GR3,=12 ;qの長さ
LD GR0,=#B1D0 ;B列に置換語を読み込む
CALL REPLACE
RPOP
RET
ARETSU DC #0000 ;A列0語目
DC #0000
DC #0000
DC #5555 ;A列3語目(置換対象)
DC #5555 ;A列4語目(置換対象)
DC #0000
REPLACE
RPUSH
LD GR4,GR2 ;GR4←p置換開始位置を設定
SRL GR4,4 ;GR4←p/16 A列の先頭語から何語後ろかを求めている
ADDA GR1,GR4 ;GR1を置換対象後(この場合第3語)に位置付ける
AND GR2,=#000F ;第3語目の何ビットから置換するのか(7ビット)求めている
LD GR4,=16 ;第3語で置換する分のビット数の計算の為
SUBA GR4,GR2 ;16-7で3語目の対象ビットは9ビット
LD GR5,GR0 ;置換するB列を退避
LD GR6,=#8000 ;置換する時に使うマスクを作る
SUBA GR3,=1 ;マスクを作る時にシフトするビットの調整
SRA GR6,0,GR3 ;注意!SRAで「算術」シフトだから空いた所に1が入る
LD GR7,GR6 ;マスクを退避する
SRL GR0,0,GR2 ;置換するB列を7ビット右にシフトする
SRL GR6,0,GR2 ;置換に使うマスクを7ビットシフトする
SLL GR5,0,GR4 ;ビット列Aの4語目の置換に使用
SLL GR7,0,GR4 ;ビット列Aの4語目の置換に使用
LD GR2,0,GR1 ;ビット列Aの3語目を読み込む
AND GR6,GR2 ;ビット列Aの置換対象の前の部分をマスクで0にする
XOR GR2,GR6 ;排他的論理和で置換対象の部分を0にする
OR GR2,GR0 ;ビット列Bを足しこむ
ST GR2,0,GR1 ;ビット列Aの3語目に格納する
LD GR2,1,GR1 ;ビット列Aの4語目を読み込む
AND GR7,GR2 ;ビット列Aの置換対象の語の後ろの部分をマスクで0にする
XOR GR2,GR7 ;排他的論理和で置換対象の部分を0にする
OR GR2,GR5 ;ビット列Bの退避しておいた部分を足しこむ
ST GR2,1,GR1 ;ビット列Aの4語目に格納する
RPOP
RET
END
トレースに使ったノートです。