條件轉移指令是指在滿足一定條件時進行相對轉移。
判A內(nei) 容是否為(wei) 0轉移指令
JZ rel
JNZ rel
第一指令的功能是:如果(A)=0,則轉移,不然次序執行(執行本指令的下一條指令)。轉移到什麽(me) 地方去呢?如果按照傳(chuan) 統的辦法,就要算偏移量,很麻煩,好在現在我們(men) 能借助於(yu) 機器匯編了。因此這第指令我們(men) 能這樣理解:JZ 標號。即轉移到標號處。下麵舉(ju) 一例說明:
MOV A,R0
JZ L1
MOV R1,#00H
AJMP L2
L1: MOV R1,#0FFH
L2: SJMP L2
END
在執行上麵這段程序前如果R0中的值是0的話,就轉移到L1執行,因此最終的執行結果是R1中的值為(wei) 0FFH。而如果R0中的值不等於(yu) 0,則次序執行,也就是執行 MOV R1,#00H指令。最終的執行結果是R1中的值等於(yu) 0。
第一條指令的功能清楚了,第二條當然就好理解了,如果A中的值不等於(yu) 0,就轉移。把上麵的那個(ge) 例程中的JZ改成JNZ試試吧,看看程序執行的結果是什麽(me) ?
比較轉移指令
CJNE A,#data,rel
CJNE A,direct,rel
CJNE Rn,#data,rel
CJNE @Ri,#data,rel
第一條指令的功能是將A中的值和立即數data比較,如果兩(liang) 者相等,就次序執行(執行本指令的下一條指令),如果不相等,就轉移,同樣地,我們(men) 能將rel理解成標號,即:CJNE A,#data,標號。這樣利用這條指令,我們(men) 就能判斷兩(liang) 數是否相等,這在很多場合是非常有用的。但有時還想得知兩(liang) 數比較之後哪個(ge) 大,哪個(ge) 小,本條指令也具有這樣的功能,如果兩(liang) 數不相等,則CPU還會(hui) 反映出哪個(ge) 數大,哪個(ge) 數小,這是用CY(進位位)來實現的。如果前麵的數(A中的)大,則CY=0,不然CY=1,因此在程序轉移後再次利用CY就可判斷出A中的數比data大還是小了。
例:
MOV A,R0
CJNE A,#10H,L1
MOV R1,#0FFH
AJMP L3
L1: JC L2
MOV R1,#0AAH
AJMP L3
L2: MOV R1,#0FFH
L3: SJMP L3
上麵的程序中有一條單片機指令我們(men) 還沒學過,即JC,這條指令的原型是JC rel,作用和上麵的JZ類似,但是它是判CY是0,還是1進行轉移,如果CY=1,則轉移到JC後麵的標號處執行,如果CY=0則次序執行(執行它的下麵一條指令)。
分析一下上麵的程序,如果(A)=10H,則次序執行,即R1=0。如果(A)不等於(yu) 10H,則轉到L1處繼續執行,在L1處,再次進行判斷,如果(A)>10H,則CY=1,將次序執行,即執行MOV R1,#0AAH指令,而如果(A)<10H,則將轉移到L2處指行,即執行MOV R1,#0FFH指令。因此最終結果是:本程序執行前,如果(R0)=10H,則(R1)=00H,如果(R0)>10H,則(R1)=0AAH,如果(R0)<10H,則(R1)=0FFH。
弄懂了這條指令,其它的幾條就類似了,第二條是把A當中的值和直接地址中的值比較,第三條則是將直接地址中的值和立即數比較,第四條是將間址尋址得到的數和立即數比較,這裏就不詳談了,下麵給出幾個(ge) 對應的例程。
CJNE A,10H ;把A中的值和10H中的值比較(注意和上題的區別)
CJNE 10H,#35H ;把10H中的值和35H中的值比較
CJNE @R0,#35H ;把R0中的值作為(wei) 地址,從(cong) 此地址中取數並和35H比較
循環轉移指令
DJNZ Rn,rel
DJNZ direct,rel
第一條指令在前麵的例程中有詳細的分析,這裏就不多談了。第二條指令,隻是將Rn改成直接地址,其它一樣,也不多說了,給一個(ge) 例程。
DJNZ 10H,LOOP
3.調用與(yu) 返回指令
(1)主程序與(yu) 子程序 在前麵的燈的實驗中,我們(men) 已用到過了子程序,隻是我們(men) 並沒有明確地介紹。子程序是幹什麽(me) 用的,為(wei) 什麽(me) 要用子程序技術呢?舉(ju) 個(ge) 例程,我們(men) 數據老師布置了10道算術題,經過觀察,每一道題中都包含一個(ge) (3*5+2)*3的運算,我們(men) 能有兩(liang) 種選擇,第一種,每做一道題,都把這個(ge) 算式算一遍,第二種選擇,我們(men) 能先把這個(ge) 結果算出來,也就是51,放在一邊,然後要用到這個(ge) 算式時就將51代進去。這兩(liang) 種辦法哪種更好呢?不必多言。設計程序時也是這樣,有時一個(ge) 功能會(hui) 在程序的不一樣地方反複使用,我們(men) 就能把這個(ge) 功能做成一段程序,每次需要用到這個(ge) 功能時就“調用”一下。
(2)調用及回過程:主程序調用了子程序,子程序執行完之後必須再回到主程序繼續執行,不能“一去不回頭”,那麽(me) 回到什麽(me) 地方呢?是回到調用子程序的下麵一條指令繼續執行(當然啦,要是還回到這條指令,不又要再調用子程序了嗎?那可就沒完沒了了……)。參考圖1
調用指令
LCALL addr16 ;長調用指令
ACALL addr11 ;短調用指令
上麵兩(liang) 條指令都是在主程序中調用子程序,兩(liang) 者有一定的區別,但在開始學習(xi) 單片機的這些指令時,能不加以區別,而且能用LCALL 標號,ACALL 標號,來理解,即調用子程序。
(5)返回指令則說了,子程序執行完後必須回到主程序,如何返回呢?隻要執行一條返回指令就能了,即執行 ret指令
4.空操作指令
nop 就是 空操作,就是什麽(me) 事也不幹,停一個(ge) 周期,一般用作短時間的延時。