スライド 1: as-4. 条件分岐と繰り返し
スライド 2: 条件分岐とは
スライド 3: 例題1.2数の最大値
スライド 4
スライド 5
スライド 6
スライド 7
スライド 8
スライド 9
スライド 10: 例題2.条件分岐
スライド 11
スライド 12
スライド 13
スライド 14
スライド 15
スライド 16
スライド 17
スライド 18
スライド 19
スライド 20: ステータスレジスタ
スライド 21: コンディションコードレジスタの フラグの振る舞い
スライド 22: (参考)MOVE 命令でのコンディションコードレジスタの変化
スライド 23: 例題3.繰り返し
スライド 24: 繰り返しの一般形
スライド 25
スライド 26
スライド 27: 例題4.ワードデータの配列
スライド 28: 実行前
スライド 29: 実行後
スライド 30
スライド 31
スライド 32
スライド 33: オペランドの#の意味
スライド 34: 記法 (%a0)
スライド 35: lea 命令と move 命令
スライド 36: 例題5.文字列の長さ
スライド 37: 実行後
スライド 38: ASCIIコード
スライド 39: ASCIIコード表
スライド 40: 文字列
スライド 41
スライド 42
スライド 43
スライド 44: おわりに
as
-4.
条件分岐と繰り返し
1
金子邦彦
(
68000
アセンブラプ
ログラミング
)
URL:
https://www.kkaneko.jp/cc/as/index.ht
ml
条件分岐とは
Y
es
No
B
A
条件
•
「ある条件」が成り立てば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
のとき
のとき
=
=
x
y
x
x
y
(一部の内容は,復習を兼ねる)
ロングワード
1ロングワードは4バイト
それぞ
れ、1
ロング
ワードの
データエ
リア
をメモリ中に確保
プログラム中で使用
.1
ロングワード(4バイト)
.w
ワード(2バイト)
.b
バイト(1バイト)
x
と
5
の比較
(
D0
を使用)
x > 5
のとき実行
される部分
x > 5
が成り立たない
とき実行される部分
比較結果による分岐
実行順
①
②
③
④
⑤
⑥
⑦
⑧
以後省略
ジャンプ
分岐命令
ラベル
endif1
へ
分岐せよという指示
※
bra
は必ず分岐する
x > 5
のとき実
行される部分
もし
x
>
5
ならば
分岐しない
スキップ
①
②
③
④
⑤
以後省略
ジャンプ
ラベル
e
lse1
へ分岐
せよという指示
実行順
もし
x
≦
5
ならば
x>5
が成り立たないとき
実行される部分
分岐する
スキップ
moveq.l
#5,
%d0
cmp.l
x
,
%d0
bcc
else1
D0
に
0x00
00 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
に
0x00
00 0005
を入れる
x
の中身と
D0
の比較
(メモリからの読み出し)
cmp.l
x
,
%d0
bcc
else1
条件分岐の一般形
<コンディションコードレジスタを変化させる命令>
<条件分岐命令>
cmp
など
bhi, bcc, beq
bne, bcs, bls
など
5(
数値
)
と
X
の中身を比較.
比較結果による条件分岐
算術演算ユニット
Arithmet
ic and Logic
Unit
0
0
0
0
0
0
05
アドレスバス
データバス
制御系
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」を示
すときにのみ,プログラムカウンタ
に新しい値が入る
→
分岐
ステータスレジスタ
S
I0
I1
I2
C
V
Z
X
N
13
10
9
8
4
3
2
1
0
?
?
?
?
?
?
?
?
?
CCR
ステータスレ
ジスタ(16ビット)
の下位1バイトが,コンディション
コードレジスタ(CCR)
コンディションコードレジスタの
フラグの振る舞い
•
フラグは
X, N, Z, V, C
の5つ
•
フラグはすべて1ビット(0か1の値をとる)
cmp
命令での振る舞い
cmp.l
<ソース
>
,
<ディ
スティネー
シ
ョン>
2つの
比較
N
フラグ
:
<ディステ
ィネーション>
ー
<ソース>
< 0
なら
1
さもなければ
0
Z
フラグ
:
<ディステ
ィネーション>
ー
<ソース>
= 0
なら
1
さもなければ
0
※ cmp
命令以外でも
CCR
の値は変化する
2
数の引き算の結果
(参考)
MOVE
命令でのコンディ
ションコード
レジスタの変化
X:
変化せず
N:
転送結果の「最上位ビット」が1ならセ
ット(1)、
それ以外はリセット(0)
Z:
転送結果が「全てのビット」が0ならセ
ット(1)、
それ以外はリセット(0)
V
:
常にリセット(0)
C:
常にリセット(0)
※
2つの比較ではなく、
「転送したデータ」の値に
よる変化
例題3.繰り返し
•
次の例で、条件分岐命令を見る
=
=
3
1
i
i
s
繰り返しの一般形
•
何かの処理の繰り返し
•
繰り返しのたびに
条件分岐命令が実行
さ
れ,
指定された条件が成り立たない限り,
実行が繰り返される
条件
X
No
Y
es
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ワードの確保
(初期値は不定)
「1
0」ワ
ード分
のデ
ー
タエリ
アを
確保
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
#0x
1000
,
%d0
→
メモリの読み書きを行わない
–
#無し
:
メモリアドレスなどを
表す
move.w
ADDR
,
%d0
→
メモリの読み書きを行う
•
擬似命令
では
–
ふつう
#
はない.例えば
.
equ
ADDR
0xffff00
.org
0x
0400
.dc.w
0x
4848
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バイト)
プログラム本体そ
のものが
入っているエリア
未使用
文字列の末端を
示す
0
ASCII
コード
•
パソコン,ワークステーションで英数文
字
データを扱うときの標準
ASCII
コード表
0
1
2
3
4
5
6
7
0
NULL
DEL
SP
0
@
P
p
1
SOH
DC1
!
1
A
Q
a
q
2
STX
DC2
“
2
B
R
b
r
3
ETX
DC3
#
3
C
S
c
s
4
EOT
DC4
$
4
D
T
d
t
5
ENQ
NAK
%
5
E
U
e
u
6
ACK
SYN
&
6
F
V
f
v
7
BEL
ETB
’
7
G
W
g
w
8
(
BS
)
CAN
(
8
H
X
h
x
9
(
HT)
EM
)
9
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,
..., 0x0000001
1
•
条件分岐、繰り返しには,
分岐命令
が登場
する
•
分岐命令では,
プログ
ラムカ
ウンタ
の強制
的な書
き換え
が起こる
•
比較命令などで,
コン
ディシ
ョン
コード
レジス
タ
(ステータスレジスタの下位1
バイト)
が変化
.分岐命令で利用され
る
おわりに