as-4. 条件分岐と繰り返し
1
金子邦彦
68000アセンブラプログラミング
URL: https://www.kkaneko.jp/cc/as/index.html
条件分岐とは
Yes
No
条件
「ある条件」が成り立てばAを、成り立たな
ければBを実行
例題1.2数の最大値
データレジスタ D0, データレジスタ D1 のう
ち大きい方をデータレジスタ D2 にセットす
例) D0 の中身: 0x 0000 0030
D1 の中身: 0x 0000 0040
のとき
D2 の中身: 0x 0000 0040
.text
cmp.l %d0,%d1
bhi ELSE1 /* d1 > d0 */
move.l %d0,%d2
bra ENDIF1
ELSE1:
move.l %d1,%d2
ENDIF1:
.dc.w 0x4848
stop #0
.end
条件が成り立つ場合
実行される部分
条件分岐命令
条件が成り立たない場合
に実行される部分
比較命令 (D0 D1 の比較)
.text
cmp.l %d0,%d1
bhi ELSE1 /* d1 > d0 */
move.l %d0,%d2
bra ENDIF1
ELSE1:
move.l %d1,%d2
ENDIF1:
.dc.w 0x4848
stop #0
.end
実行順
D1 の中身 > D0 の中身」が成り立つ場合
.text
cmp.l %d0,%d1
bhi ELSE1 /* d1 > d0 */
move.l %d0,%d2
bra ENDIF1
ELSE1:
move.l %d1,%d2
ENDIF1:
.dc.w 0x4848
stop #0
.end
実行順
D1 の中身 > D0 の中身」が成り立たない場合
cmp.l %d0,%d1
bhi ELSE1 /* d1 > d0 */
条件分岐の一般形
<コンディションコードレジスタを変化させる命令>
<条件分岐命令>
cmp など
bhi, bcc, beq
bne, bcs, bls など
D0, D1 の中身を比較.
比較結果による条件分岐
cmp.l %d0,%d1
bhi ELSE1 /* d1 > d0 */
条件分岐命令
分岐する条件
bhi
D0の中身 D1の中身
bcc
D0の中身 D1の中身
beq
D0の中身 D1の中身
bne
D0の中身 D1の中身
bcs
D0の中身 D1の中身
bls
D0の中身 D1の中身
cmp.l %d0,%d1
bhi ELSE1 /* d1 > d0 */
分岐条件
bhi, bcc, beq
bne, bcs, bls など
分岐先の
メモリアドレス
プログラムカウンタ
にセットされる
例題2.条件分岐
条件分岐の例として,次の例を考え
)5( 0
)5( 8
のとき
のとき
=
=
xy
xxy
(一部の内容は,復習を兼ねる)
ロングワード
1ロングワードは4バイト
それぞれ、1ロングワードの
データエリアをメモリ中に確保
プログラム中で使用
.1 ロングワード(4バイト)
.w ワード(2バイト)
.b バイト(1バイト)
x 5 の比較
D0 を使用)
x > 5 のとき実行
される部分
x > 5 が成り立たない
とき実行される部分
比較結果による分岐
実行順
以後省略
ジャンプ
分岐命令
ラベル endif1
分岐せよという指示
bra は必ず分岐する
x > 5 のとき実
行される部分
もし x5 ならば
分岐しない
スキップ
以後省略
ジャンプ
ラベル else1へ分岐
せよという指示
実行順
もし x5 ならば
x>5 が成り立たないとき
実行される部分
分岐する
スキップ
moveq.l #5,%d0
cmp.l x,%d0
bcc else1
D0 0x0000 0005 を入れる
x の中身と D0 の比較
メモリからの読み出し
D0 を比較のために使用
5(数値) X の中身を比較.
比較結果による条件分岐
moveq.l #5,%d0
cmp.l x,%d0
bcc else1
この場合の意味
bhi xの中身 D0の中身
bcc xの中身 D0の中身
beq xの中身 D0の中身
bne xの中身 D0の中身
bcs xの中身 D0の中身
bls xの中身 D0の中身
分岐条件
bhi
bcc
beq
bne
bcs
bls
条件分岐条件
D0 0x0000 0005 を入れる
x の中身と D0 の比較
(メモリからの読み出し)
cmp.l x,%d0
bcc else1
条件分岐の一般形
<コンディションコードレジスタを変化させる命令>
<条件分岐命令>
cmp など
bhi, bcc, beq
bne, bcs, bls など
5(数値) X の中身を比較.
比較結果による条件分岐
算術演算ユニット
Arithmetic and Logic Unit
00000005
アドレスバス
データバス
制御系
Control Unit
+命令長
レジスタ
Registers
R/W
引き算の結果が,0
か正か負かによって
CCRの値が定まる
cmp.l x,%d0」の実行では
D0
xの中身
00000005
x
「引き算」が
実行される
アドレスバス
データバス
制御系
Control Unit
+命令長
R/W
bcc else1」の実行では
プログラムカウンタ
Program Counter
メモリ
CCR の値が
「引き算の結果が正または0」を示
すときにのみ,プログラムカウンタ
に新しい値が入る
分岐
ステータスレジスタ
I0
I1
I2
13 10
?
?
?
?
?
?
?
?
?
CCR
ステータスレジスタ(16ビット)
の下位1バイトが,コンディション
コードレジスタ(CCR)
コンディションコードレジスタの
フラグの振る舞い
フラグは X, N, Z, V, C の5つ
フラグはすべて1ビット(0か1の値をとる)
cmp 命令での振る舞い
cmp.l <ソース, <ディスティネーョン>
2つの比較
Nフラグ: <ディスティネーション><ソース> < 0 なら
さもなければ
Zフラグ: <ディスティネーション><ソース> = 0 なら
さもなければ
※ cmp 命令以外でも CCR の値は変化する
2数の引き算の結果
(参考)MOVE 命令でのコンディ
ションコードレジスタの変化
X: 変化せず
N: 転送結果の「最上位ビット」が1ならセット(1)、
それ以外はリセット(0)
Z: 転送結果が「全てのビット」が0ならセット(1)、
それ以外はリセット(0)
V: 常にリセット(0)
C: 常にリセット(0)
2つの比較ではなく、
「転送したデータ」の値に
よる変化
例題3.繰り返し
次の例で、条件分岐命令を見る
=
=
3
1i
is
繰り返しの一般形
何かの処理の繰り返し
繰り返しのたびに 条件分岐命令が実行
れ, 指定された条件が成り立たない限り,
実行が繰り返される
条件
X
No
Yes
START:
命令(比較命令,演算など)
b?? QUIT
命令
命令
bra START
QUIT:
繰り返し
繰り返しの終了条件
D0 の中身 <= 3」が成り立たない
D0 の中身
3 の比較
D0 の中身 > 3
のときはジャンプ
分岐条件
bhi D0 > 3
bcc D0 >= 3
beq D0 = 3
bne D0 != 3
bcs D0 < 3
bls D0 <= 3
D0 の中身 3
のとき
繰り返し
ジャンプ
繰り返しを続ける
D0 の中身
3 の比較
例題4.ワードデータの配列
10個のワードデータに,順に,0000, 0001,
0002, ・・・, 0009 をセットするプログラム
実行前
10ワード(=20バイト)
のデータエリア
プログラム本体そのものが
入っているエリア
未使用
実行後
10ワード(=20バイト)
のデータエリア
プログラム本体そのものが
入っているエリア
未使用
「10」ワード分のデー
タエリア確保
.1 ロングワード(4バイト)
.w ワード(2バイト)
.b バイト(1バイト)
.dc.w 10
1ワードの確保.
初期値を10にセット
.ds.w 10
10ワードの確保
(初期値は不定)
「10」ワード分のデ
タエリアを確保
D0 をクリア (0x0000 D0 の下2バイト)
ラベル a のメモリアドレスを A0 にセット
0x00000020 A0
D0 9 の比較
比較結果による分岐
繰り返し実行
ラベル a のメモリアドレスを A0 にセット
0x00000020 A0
A0がポイントしている
メモリアドレスに,D0 の中身を
書き込む
D0 + 1 D0 (2バイト)
0x0000, 0x0001, 0x0002,
..., 0x0009
A0 + 1 A0
0x00000020, 0x00000022,
..., 0x00000032
オペランドの#の意味
プログラム命令では
#付き 値を表す
move.w #0x1000, %d0
メモリの読み書きを行わない
#無し メモリアドレスなどを表す
move.w ADDR, %d0
メモリの読み書きを行う
擬似命令では
ふつう はない.例えば
.equ ADDR 0xffff00
.org 0x0400
.dc.w 0x4848
a: .ds.w 1
記法 (%a0)
move.w %d0, (%a0)
D0 の中身を,A0がポイントしている
メモリアドレスに書き込
A0 の値が 0x00000020 なら
0x20, 0x21 番地に,D0 の下2バイトを書き込む
メモリへの書き込み
move.l %d0, %a0
D0 の中身を A0 の中にコピー
メモリの読み書き無し
lea 命令と move 命令
lea s, %a0
ラベル s が示すメモリアドレス A0 に格納
0x00000020 A0
メモリアクセス無し
move.l s, %a0
ラベル s が示すメモリ中身 A0 に格納
0x00000020 の中身 4バイト分> A0
メモリからの読み出し
例題5.文字列の長さ
文字列の長さを数えるプログラム
今回の文字列データ: My Name is David!
文字列の先頭から1文字ずつ読み
0 で無ければ,「データレジスタD0 に1を足す」こと
繰り返す
0 ならば処理を終える
実行後
文字列のデータ
(1文字で1バイト)
プログラム本体そのものが
入っているエリア
未使用
文字列の末端を
示す
ASCIIコード
パソコン,ワークステーションで英数文
データを扱うときの標準
ASCIIコード表
NULL DEL SP
P p
SOH DC1
A Q a q
STX DC2
B R b r
ETX DC3
C S c s
EOT DC4
D T d t
ENQ NAK
E U e u
ACK SYN
F V f v
BEL ETB
G W g w
BS
CAN
H X h x
HT)
EM
I Y i y
A
LF)
SUB
J Z j z
B
VT)
ESC
K
k {
C
FF) FS)
L
l |
D
CR) GS)
M
m }
E SO
RS)
N
n ~
F SI
US)
O
_
o DEL
青は特別用途
の1バイトデータ
緑は英数文字
データ
文字列
My Name is David! のように英数文
字が並んだもの
各1文字は1バイト
末尾の0x00 (これで1バイト)
文字列の終わりを意味する (文字列の長
さは変化するので,終わりを示すための
号が必要」
文字列データのデータ
エリア確保
アセンブラプログラム中での
文字列の書き方
.ascii "<文字列> 0"
ラベル str1 のメモリアドレスを A0 にセット
0x00000020 A0
D0 をクリア (0x00000000 D0)
0 との比較
(文字列の末端か?)
繰り返し実行
A0 + 1 A0
0x00000020, 0x00000021,
..., 0x00000031
D0 + 1 D0
0x00000000, 0x00000001,
..., 0x00000011
条件分岐、繰り返しには,分岐命令が登場
する
分岐命令では,プログラムカウンタの強制
的な書き換えが起こる
比較命令などで,コンディションコード
レジス(ステータスレジスタの下位1
バイト)が変化.分岐命令で利用され
おわりに