(8)循環指令oop
循環結構是程序的三大結構之一。爲了方便構成循環結構,彙編語言提供了多種循環指令,這些循環指令的循環次數都是保存在計數器CX或ECX中。除了CX或ECX能夠決定循環是否結束外,有的循環指令還可由標誌位ZF來決定是否結束循環。blog
在高級語言中,循環計數器能夠遞增,也可遞減,但彙編語言中,CX或ECX只能遞減,因此,循環計數器只能從大到小。在程序中,必須先把循環次數賦給循環計數器。ip
彙編語言的循環指令都是放在循環體的下面,在循環時,首先執行一次循環體,而後把循環計數器CX或ECX減1。當循環終止條件達到知足時,該循環指令下面的指令將是下一條被執行的指令,不然,程序將向上轉到循環體的第一條指令。get
在循環未終止,而向上轉移時,規定:該轉移只能是一個短轉移,即偏移量不能超過128,也就是說循環體中全部指令碼的字節數之和不能超過128。若是循環體過大,能夠用後面介紹的「轉移指令」來構造循環結構。it
循環指令自己的執行不影響任何標誌位。變量
1、循環指令(Loop Until Complete)cli
循環指令LOOP的通常格式:bfc
LOOP 標號循環
LOOPW 標號 ;CX做爲循環計數器,80386+程序
LOOPD 標號 ;ECX做爲循環計數器,80386+
循環指令的功能描述:
(CX)=(CX)-1或(ECX)=(ECX)-1;
若是(CX)≠0或(ECX)≠0,轉向「標號」所指向的指令,不然,終止循環,執行該指令下面的指令。
例5.13 編寫一段程序,求1+2+…+1000之和,並把結果存入AX中。
解:
方法1:由於計數器CX只能遞減,因此,可把求和式子改變爲:1000+999+…+2+1。
…
XOR AX, AX
MOV CX, 1000D
again: ADD AX, CX ;計算過程:1000+999+…+2+1
LOOP again
…
方法2:不用循環計數器進行累加,求和式子仍爲:1+2+…+999+1000。
…
XOR AX, AX
MOV CX, 1000D
MOV BX, 1
again: ADD AX, BX ;計算過程:1+2+…+999+1000
INC BX
LOOP again
…
從程序段的效果來看:方法1要比方法2好。
2、相等或爲零循環指令(Loop While Equal or Loop While Zero)
相等或爲零循環指令的通常格式:
LOOPE/LOOPZ 標號
LOOPEW/LOOPZW 標號 ;CX做爲循環計數器,80386+
LOOPED/LOOPZD 標號 ;ECX做爲循環計數器,80386+
這是一組有條件循環指令,它們除了要受CX或ECX的影響外,還要受標誌位ZF的影響。其具體規定以下:
(1)、(CX)=(CX)-1或(ECX)=(ECX)-1; (不改變任何標誌位)
(2)、若是循環計數器≠0且ZF=1,則程序轉到循環體的第一條指令,不然,程序將執行該循環指令下面的指令。
3、不等或不爲零循環指令(Loop While Not Equal or Loop While Not Zero)
不等或不爲零循環指令的通常格式:
LOOPNE/LOOPNZ 標號
LOOPNEW/LOOPNZW 標號 ;CX做爲循環計數器,80386+
LOOPNED/LOOPNZD 標號 ;ECX做爲循環計數器,80386+
這也是一組有條件循環指令,它們與相等或爲零循環指令在循環結束條件上有點不一樣。其具體規定以下:
(1)、(CX)=(CX)-1或(ECX)=(ECX)-1; (不改變任何標誌位)
(2)、若是循環計數器≠0且ZF=0,則程序轉到循環體的第一條指令,不然,程序將執行該循環指令下面的指令。
4、循環計數器爲零轉指令(Jump if CX/ECX is Zero)
在前面的各種循環指令中,無論循環計數器的初值爲什麼,循環體至少會被執行一次。當循環計數器的初值爲0時,一般的理解應是循環體被循環0次,即循環體一次也不被執行。其實否則,循環體不是不被執行,而是會被執行65536次(用CX計數)或4294967296次(幾乎是死循環,用ECX計數)。
爲了解決指令的執行和常規思惟之間差別,指令系統又提供了一條與循環計數器有關的指令——循環計數器爲零轉指令。該指令通常用於循環的開始處,其指令格式以下:
JCXZ 標號 ;當CX=0時,則程序轉移標號處執行
JECXZ 標號 ;當ECX=0時,則程序轉移標號處執行,80386+
例5.14 編寫一段程序,求1+2+…+k(K≥0)之和,並把結果存入AX中。
解:
…
K DB ? ;變量定義
…
XOR AX, AX
MOV CX, K
JCXZ next
again: ADD AX, CX ;計算過程: K+(K-1)+…+2+1
LOOP again
next: …
思考題:假設變量K的值爲0,而且在循環體的前面沒有寫指令「JCXZ next」,這時求出的「和」AX的值是什麼?