6. 64 位元組合語言
執行 sum.bat 結果如下:
C:asm64ch05>sum.exe
element 9 at position (from 0) = 4
5.7 選擇結構
選擇結構從一個或多個情況中選擇您所要的,然後執行指定的指令。例如您的
程式中可以檢查某一個變數 ch2 值,當它的值是 'a' 時就將 'A' 存入 ch2 變數
中。程式片段如下:
; if ch2='a' then ch2='A'
MOV AL, [ch2] ; 變數 ch2 內含值拷貝至 AL
CMP AL, 'a' ;AL 內含值與 'a' 比較
JNE next ; 不相等時跳至 next
MOV BYTE[ch2],'A' ; 相等時將 'A' 存入 ch2 變數中
next:
使用組合語言時,您必須將條件的建立與檢查比較的結果分開成兩個指令,條
件的建立可以使用 CMP 指令,兩個運算元比較的結果會設定相對應的狀態旗標值,
檢查比較的結果可使用條件跳躍指令,直接測試狀態旗標值,滿足指定的條件才跳
躍至指定的標籤位址。上例中比較變數 ch2 的內含值及 'a' 立即值,滿足相等條
件時才將 'A' 存入 ch2 變數中,否則跳至 next 標籤處繼續執行。這種結構稱為
單選的 if 結構。
圖 5.4 單選的 if 結構
94
7. CHAP T ER 05
《 程式流程控制 選擇結構 》
在 上 一 個 例 題 中, 條 件 是「CMP AL,'a'」 指 令, 條 件 跳 躍 指 令「JNE
next」判斷不為 'a' 時才跳至 next,否則就執行「MOV BYTE[ch2],'A'」指
令,這個指令就是當條件成立時您所要執行的指令。
在本章後面的幾個例子都會用到有關字元的處理,字元在電腦記憶體裡面是以
二進位的方式儲存的,個人電腦一般使用 ASCII 碼以一個位元組來表示一個字元,
例如字元 'A' 以「0100 0001」二進位的方式儲存,以十六進位表示為 41H,以
十進位表示為 65,您要從鍵盤輸入 'A' 字元,可以透過巨集 scanvar,其使用
方法如下列程式所示。
;*************** hexval.asm ***************
%include "..binnasm64io.mac"
SECTION .data
msg DB 'please keyin a character: ',0
format DB '%c',0
format2 DB '%c = %02I64xH',0
SECTION .bss
char RESB 2
SECTION .text
start:
prnstr msg
scanvar format, char
prn2vars format2, [char], [char]
RET
執行 hexval.bat 結果如下:
C:asm64ch05>hexval.exe
please keyin a character: C <Enter>
C = 43H
95
8. 64 位元組合語言
程式 compchar.asm 說明單選 if 結構的用法。從鍵盤輸入一字元至 ch2 記
憶體位址。變數 ch2 的內含值與字元 'a' 比較,不相等時跳至 L2 標籤,將 ch2
的值顯示出來,若 ch2 的值等於 'a' 時設定值為 'A' 後才將 ch2 的值列印出來。
;****************** compchar.asm *****************
%include "..binnasm64io.mac"
SECTION .data
msg DB 'please keyin a character: ',0
format DB '%c',0
format2 DB 'the result character = %c',0
SECTION .bss
ch2 RESB 2
SECTION .text
start:
prnstr msg ; 印出 msg 字串
scanvar format, ch2 ; 鍵入字元至 ch2
MOV AL, [ch2] ; 拷貝 ch2 變數值至 AL
CMP AL, 'a' ;AL 內含值與 'a' 比較
JNE L2 ; 不相等時跳至 L2
MOV AL, 'A'
MOV BYTE [ch2], AL ; 相等時將 [ch2] 換為 'A'
L2: prnvar format2, [ch2] ; 輸出結果
RET
執行 compchar.bat 結果如下:
C:asm64ch05>compchar.exe
please keyin a character: a <Enter>
the result character = A
C:asm64ch05>compchar.exe
please keyin a character: c <Enter>
the result character = c
有時測試條件成立時要執行這些指令,條件不成立時要執行那些指令,也就是
說測試之前程式是一條主流,測試後不是執行這個支流的指令,就是執行那個支流
的指令,不管是這支或那支,最後又合流成一個主流。
96
9. CHAP T ER 05
《 程式流程控制 選擇結構 》
圖 5.5 二選一的 if 結構
以程式 if.asm 為例,比較輸入的字元是否高於 'D',若是高於 'D' 則跳至
標籤 L4 處執行,顯示不及格訊息。若是低於或等於 'D' 則顯示及格訊息後跳至
L2 處結束程式之執行。稱為二選一的 if 結構,流程圖如上圖所示。
;******************* if.asm *******************
%include "..binnasm64io.mac"
SECTION .data
msg DB 'keyin a character (A-F): ',0
format DB '%c',0
pass DB 'pass',13,10,0
fail DB 'fail',13,10,0
SECTION .bss
ch2 RESB 2
SECTION .text
start:
prnstr msg ; 列印 msg 字串
scanvar format, ch2 ; 依 format 格式輸出 ch2
MOV AL, [ch2] ; 拷貝 ch2 變數值至 AL
CMP AL, 'D' ;AL 內含值與 'D' 比較
97
10. 64 位元組合語言
JA L4 ; 高於 'D' 時跳至 L4
L2: prnstr pass ;A/B/C/D 顯示 pass 及格
RET
L4: prnstr fail ;E/F 顯示 fail 不及格
RET
執行 if.bat 結果如下:
C:asm64ch05>if.exe
keyin a character (A-F): B <Enter>
pass
C:asm64ch05>if.exe
keyin a character (A-F): E <Enter>
fail
有時測試的條件不只兩種情形,這時您要一個條件一個條件逐一測試,滿足第
一種條件就跳至第一標籤執行,滿足第二種條件就跳至第二標籤執行,滿足第三種
條件就跳至第三標籤執行,等等,最後又合流至主流。
圖 5.6 多選一的 switch 結構
98