除非執行控制傳輸指令,否則程序流按順序從一條指令轉到下一條指令。彙編語言中的各種控制轉移指令包括有條件或無條件跳轉和調用指令。
Loop and Jump Instructions
Looping in the 8051
重複一系列指令一定次數稱爲a循環。指令DJNZ reg,label用於執行循環操作。在該指令中,寄存器遞減1;如果不是0,則8051跳轉到標籤所指的目標地址。
在循環開始之前,寄存器加載有重複次數的計數器。在這條指令中,寄存器減量和跳轉決定被組合成一條指令。寄存器可以是R0到R7中的任何一個。計數器也可以是RAM位置。
Example
用重複加法把25乘以10
解決方案−乘法可以通過重複添加被乘數(倍於乘數)來實現。例如,
25*10=250(華氏度)
25+25+25+25+25+25+25+25+25+25+25=250
MOV A,#0 ;A = 0,clean ACC MOV R2,#10 ; the multiplier is replaced in R2 Add A,#25 ;add the multiplicand to the ACC AGAIN:DJNZ R2, AGAIN:repeat until R2 = 0 (10 times) MOV R5 , A ;save A in R5 ;R5 (FAH)
使用指令DJNZ Reg label的8051−循環操作的缺點僅限於256次疊代。如果不執行條件跳轉,則執行跳轉後的指令。
Looping inside a Loop
當我們在另一個循環中使用循環時,它被稱爲a嵌套循環。當最大計數限制爲256時,使用兩個寄存器保存計數。所以我們用這個方法重複這個動作超過256次。
示例
編寫一個程序到−
- Load the accumulator with the value 55H.
- Complement the ACC 700 times.
由於700大於255(任何寄存器的最大容量),因此使用兩個寄存器來保存計數。下面的代碼演示如何使用兩個寄存器R2和R3進行計數。
MOV A,#55H ;A = 55H NEXT: MOV R3,#10 ;R3 the outer loop counter AGAIN:MOV R2,#70 ;R2 the inner loop counter CPL A ;complement
Other Conditional Jumps
下表列出了8051中使用的條件跳轉−
Instruction | Action |
---|---|
JZ | Jump if A = 0 |
JNZ | Jump if A ≠ 0 |
DJNZ | Decrement and Jump if register ≠ 0 |
CJNE A, data | Jump if A ≠ data |
CJNE reg, #data | Jump if byte ≠ data |
JC | Jump if CY = 1 |
JNC | Jump if CY ≠ 1 |
JB | Jump if bit = 1 |
JNB | Jump if bit = 0 |
JBC | Jump if bit = 1 and clear bit |
JZ(如果A=0,則跳轉)−在此指令中,將檢查累加器的內容。如果爲零,則8051跳到目標地址。JZ指令只能用於累加器,不適用於任何其他寄存器。
JNZ(如果A不等於0,則跳轉)−在此指令中,累加器的內容被檢查爲非零。如果不是零,則8051跳到目標地址。
JNC(無進位跳轉,CY=0跳轉)−標誌(或PSW)寄存器中的進位標誌位用於決定是否跳轉「JNC label」。CPU查看進位標誌是否被提升(CY=1)。如果沒有引發,則CPU開始從標籤的地址獲取並執行指令。如果CY=1,它將不跳轉,而是執行JNC下面的下一條指令。
JC(如果進位則跳轉,如果CY=1則跳轉)−如果CY=1,則跳轉到目標地址。
JB(高位跳)
JNB(位低時跳轉)
注意−必須注意,所有條件跳轉都是短跳轉,即目標地址必須在程序計數器內容的–128到+127位元組範圍內。
Unconditional Jump Instructions
8051中有兩個無條件跳轉&負;
LJMP(跳遠)−LJMP是3位元組指令,其中第一個字節表示操作碼,第二個和第三個字節表示目標位置的16位地址。2位元組的目標地址允許從0000跳到FFFFH的任何內存位置。
SJMP(short jump)−它是一個2位元組的指令,其中第一個字節是操作碼,第二個字節是目標位置的相對地址。相對地址的範圍從00H到FFH,分爲向前和向後跳轉;也就是說,相對於當前PC(程序計數器)的地址,在-128到+127位元組的內存內。在前向跳轉的情況下,目標地址可以在當前PC 127位元組的空間內。在後向跳轉的情況下,目標地址可以在當前PC–128位元組的空間內。
Calculating the Short Jump Address
所有條件跳轉(JNC、JZ和DJNZ)都是短跳轉,因爲它們是2位元組指令。在這些指令中,第一個字節表示操作碼,第二個字節表示相對地址。目標地址總是相對於程序計數器的值。爲了計算目標地址,第二個字節被添加到跳轉下面的指令的PC中。看看下面給出的程序;
Line PC Op-code Mnemonic Operand 1 0000 ORG 0000 2 0000 7800 MOV R0,#003 3 0002 7455 MOV A,#55H0 4 0004 6003 JZ NEXT 5 0006 08 INC R0 6 0007 04 AGAIN: INC A 7 0008 04 INC A 8 0009 2477 NEXT: ADD A, #77h 9 000B 5005 JNC OVER 10 000D E4 CLR A 11 000E F8 MOV R0, A 12 000F F9 MOV R1, A 13 0010 FA MOV R2, A 14 0011 FB MOV R3, A 15 0012 2B OVER: ADD A, R3 16 0013 50F2 JNC AGAIN 17 0015 80FE HERE: SJMP HERE 18 0017 END
Backward Jump Target Address Calculation
在向前跳躍的情況下,位移值是介於0到127(十六進位爲00到7F)之間的正數。但是,對於向後跳躍,位移爲0到-128的負值。
CALL Instructions
調用用於調用子例程或方法。子例程用於執行需要頻繁執行的操作或任務。這使得程序更加結構化,節省了內存空間。有兩個指令&負;LCALL和ACALL。
LCALL (Long Call)
LCALL是一個3位元組指令,其中第一個字節表示操作碼,第二個和第三個字節用於提供目標子程序的地址。LCALL可用於調用8051的64K字節地址空間內可用的子程序。
爲了在被調用的子程序執行之後成功地返回到該點,CPU將指令的地址保存在堆棧上LCALL的正下方。因此,當調用一個子例程時,控制權轉移到該子例程,處理器將PC(程序計數器)保存在堆棧上,並開始從新位置獲取指令。指令RET(return)在完成子例程的執行後,將控制項傳輸回調用方。每個子程序使用RET作爲最後一條指令。
ACALL (Absolute Call)
ACALL是一個2位元組的指令,而LCALL是3位元組。子例程的目標地址必須在2K字節內,因爲2位元組中只有11位用於地址。a CALL和LCALL的區別在於,LCALL的目標地址可以在8051的64K字節地址空間內的任何地方,而調用的目標地址則在2K字節範圍內。