?什么是單片機尋址方式與指令系統
通過前面的學習,我們已經了解了單片機內部的結構,并且也已經知道,要控制單片機,讓它為我們干學,要用指令,我們已學了幾條指令,但很零散,從現在開始,我們將要系統地學習8051單片機的指令部份。
一、概述
1、指令的格式
尋址方式
??? 指令的一個重要組成部分是操作數,由它指定參與運算的數據或數據所在的存儲器單元或寄存器或I/O接口的地址。指令中所規定的尋找操作數的方式就是尋址方式。每一種計算都具有多種尋址方式,尋址方式越多,計算機的功能就越強,靈活性就越大。尋址方式的多少及尋址功能是反映指令系統優劣的主要因素之一。要掌握指令系統也可從尋址方式入手。
MCS-51指令系統的尋址方式有7種:立即尋址(#data)、寄存器尋址(Rn)、間接尋址(@Ri、@DPTR)直接尋址direct、變址尋址(A+)、相對尋址(rel)和特定寄存器尋址(A)。有些書把A當寄存器尋址,把位尋址單獨作一種尋址方式,不管怎么分類其目的是為了便于記憶、掌握111條指令。
?
1.立即尋址(#data)
??? 操作數包含在指令字節中,操作數直接出現在指令中,并存放在程序存儲器中,這種方式稱為立即尋址。
立即尋址指令的操作數是一個8位或16位的二進制常數,它前面以“#”號標識,例如:ADD A,#56H,即#56H與累加器A(設為31H)內容相加,結果(87H)存于累加器A中。這條指令的機器碼為2456H.
?
2.寄存器尋址(Rn)
由指令指出某一個寄存器中的內容作為操作數,這種尋址方式稱為寄存器尋址。在這種尋址方式中,指令的操作碼中包含了參加操作的工作寄存器R0~R7的代碼(指令操作碼字節的低3位指明所尋址的工作寄存器)。例如:ADD? A,Rn中的Rn,當n為0、1、2時,機器碼分別為28、29、2A.
3.間接尋址(@Ri/@DPTR)
??? 由指令指出某一個寄存器內容作為操作數的地址。這種尋址方式稱為寄存器間接尋址。訪問外部RAM時,可使用R0,R1或DPTR作為地址指針,寄存器間接尋址用符號“@”表示。
例如:MOV A,@RO(機器碼E7)是指:若RO內容為66(內部RAM地址單元66H),而66H單元中內容是27H,則指令的功能是將27H這個數送到累加器A.
?
4.直接尋址(direct)
???? 在指令中直接給出操作數所在存儲單元的地址(一個8位二進制數),稱為直接尋址。直接地址用direct表示,
直接尋址方式中操作數存儲的空間有三種:
(1).內部數據存儲器的128個字節單元(00H~7FH)
(2).位地址空間(有些書把這種尋址方式單獨作一種尋址方式)
(3).特殊功能寄存器, 特殊功能寄存器只能用直接尋址方式進行訪問。
?
??? 5.基址加變址尋址(@A+PC/@A+DPTR)
???? 以16位寄存器(DPTR或PC)作為基址寄存器,加上地址偏移量(累加器A中的8位無符號數)形成操作數的地址。
變址尋址方式有兩類:
(1).以程序計數器的值為基址例如指令:
??? MOVC A,@A+PC;??? ;(A)←((A)+(PC))
???? 指令的功能是先使PC指向本指令下一條指令地址(本指令以完成),然后PC地址與累加器內容相加,形成變址尋址的單元地址內容送A。
? (2).以數據指針DPTR為基址,以數據指針內容和累加器內容相加形成地址,例如:
MOV DPTR #4200H ;給DPTR賦值
MOV A,#10H???? ;給A賦值
MOVC A ,@A+DPTR ;變址尋址方式(A)←((A)+(DPTR))
三條指令的執行結果是將4210H單元內容送A中。
?
6.相對尋址(rel)
??? 以程序計數器PC的當前值為基址,加上相對尋址指令的字節長度,再加上指令中給定的偏移量rel的值(rel是一個8位帶符號數,用二進制補碼表示),形成相對尋址的地址。
例如指令:
JNZ rel??? (或rel = 23H,機器碼為7023)
? 當A≠0時,程序跳到這條指令后面,相差23個字節運行下一條指令。
?
7.特定寄存器尋址
??? 累加器A和數據針DPTR這兩個使用最頻繁的寄存器又稱為特殊寄存器。對特定寄存器的操作指令,指令不再需要指出其地址字節,指令碼本身隱含了操作對象A或DPTR。
例如:
INC A?? (指令碼04)?? ;累加器加1
MOV? A,#12H?? (指令碼7412)?? ;數12送累加器
INC DPTR? (指令碼A3) ;數據指針內容加1
綜上所述,尋址方式與存儲器結構有密切關系。一種尋址方式只適合于對一部分存儲器進行操作,在使用時要加以注意。
?? 我們已知,要讓計算機做事,就得給計算機以指令,并且我們已知,計算機很“笨”,只能懂得數字,如前面我們寫進機器的75H,90H,00H等等,所以指令的第一種格式就是機器碼格式,也說是數字的形式。但這種形式實在是為難我們人了,太難記了,于是有另一種格式,助記符格式,如MOV P1,#0FFH,這樣就好記了。 這兩種格式之間的關系呢,我們不難理解,本質上它們完全等價,只是形式不一樣而已。
2、匯編
? 我們寫指令使用匯編格式,而計算機和單片機只懂機器碼格式,所以要將我們寫的匯編格式的指令轉換為機器碼格式,這種轉換有兩種辦法:手工匯編和機器匯編。手工匯編實際上就是查表,因為這兩種格式純粹是格式不一樣,所以是一一對應的,查一張表格就行了。不過手工查表總是嫌麻煩,所以就有了計算機軟件,用計算機軟件來替代手工查表,這就是機器匯編。
二、單片機的尋址
? 讓我們先來復習一下我們學過的一些指令:MOV P1,#0FFH,MOV R7,#0FFH這些指令都是將一些數據送到對應的位置中去,為什么要送數據呢?第一個因為送入的數能讓燈全滅掉,第二個是為了要實現延時,從這里我們能看出來,在用單片機的編程語言編程時,經常要用到數據的傳遞,事實上數據傳遞是單片機編程時的一項重要工作,一共有28條指令(單片機共111條指令)。下面我們就從數據傳遞類指令開始吧。
? 分析一下MOV P1,#0FFH這條指令,我們不難得出結論,第一個詞MOV是命令動詞,也就是決定做什么事情的,MOV是MOVE少寫了一個E,所以就是“傳遞”,這就是指令,規定做什么事情,后面還有一些參數,分析一下,數據傳遞必須要有一個“源”也就是你要送什么數,必須要有一個“目的”,也就是你這個數要送到什么地方去,顯然在上面那條單片機指令中,要送的數(源)就是0FFH,而要送達的地方(目的地)就是P1這個寄存器。在數據傳遞類指令中,均將目的地寫在指令的后面,而將源寫在最后。
? 這條指令中,送給P1是這個數本身,換言之,做完這條指令后,我們能明確地知道,P1中的值是0FFH,但是并不是任何時候都能直接給出數本身的。例如,在我們前面給出的單片機延時程序例是這樣寫的:
MAIN: SETB P1.0 ;(1)
LCALL DELAY ;(2)
CLR P1.0 ;(3)
LCALL DELAY ;(4)
AJMP MAIN ;(5)
;以下子程序
DELAY: MOV R7,#250 ;(6)
D1: MOV R6,#250 ;(7)
D2: DJNZ R6,D2 ;(8)
DJNZ R7,D1 ;(9)
RET ;(10)
END ;(11)
表1
-----------------------------------------------------
?MAIN: SETB P1.0 ;(1)
MOV 30H,#255
LCALL DELAY ;
CLR P1.0 ;(3)
MOV 30H,#200
LCALL DELAY ;(4)
AJMP MAIN ;(5)
;以下子程序
DELAY: MOV R7,30H ;(6)
D1: MOV R6,#250 ;(7)
D2: DJNZ R6,D2 ;(8)
DJNZ R7,D1 ;(9)
RET ;(10)
END ;(11)
表2
這樣一來,我每次調用延時程序延時的時間都是相同的(大致都是0.13S),如果我提出這樣的要求:燈亮后延時時間為0.13S燈滅,燈滅后延時0.1秒燈亮,如此循環,這樣的程序還能滿足要求嗎?不能,怎么辦?我們能把延時程序改成這樣(見表2):調用則見表2中的主程,也就是先把一個數送入30H,在子程序中R7中的值并不固定,而是根據30H單元中傳過來的數確定。這樣就能滿足要求。
?? 從這里我們能得出結論,在數據傳遞中要找到被傳遞的數,很多時候,這個數并不能直接給出,需要變化,這就引出了一個概念:如何尋找操作數,我們把尋找操作數所在單元的地址稱之為尋址。在這里我們直接使用數所在單元的地址找到了操作數,所以稱這種辦法為直接尋址。除了這種辦法之外,還有一種,如果我們把數放在工作寄存器中,從工作寄存器中尋找數據,則稱之為寄存器尋址。例:MOV A,R0就是將R0工作寄存器中的數據送到累加器A中去。提一個問題:我們知道,工作寄存器就是內存單元的一部份,如果我們選擇工作寄存器組0,則R0就是RAM的00H單元,那么這樣一來,MOV A,00H,和MOV A,R0不就沒什么區別了嗎?為什么要加以區別呢?的確,這兩條指令執行的結果是完全相同的,都是將00H單元中的內容送到A中去,但是執行的過程不一樣,執行第一條指令需要2個周期,而第二條則只需要1個周期,第一條指令變成最終的目標碼要兩個字節(E5H 00H),而第二條則只要一個字節(E8h)就能了。
? 這么斤斤計較!不就差了一個周期嗎,如果是12M的晶體震蕩器的話,也就1個微秒時間了,一個字節又能有多少?
?? 不對,如果這條指令只執行一次,也許無所謂,但一條指令如果執行上1000次,就是1毫秒,如果要執行1000000萬次,就是1S的誤差,這就很可觀了,單片機做的是實時控制的事,所以必須如此“斤斤計較”。字節數同樣如此。
再來提一個問題,現在我們已知,尋找操作數能通過直接給的方式(立即尋址)和直接給出數所在單元地址的方式(直接尋址),這就夠了嗎?
看這個問題,要求從30H單元開始,取20個數,分別送入A累加器。
?? 就我們目前掌握的辦法而言,要從30H單元取數,就用MOV A,30H,那么下一個數呢?是31H單元的,怎么取呢?還是只能用MOV A,31H,那么20個數,不是得20條指令才能寫完嗎?這里只有20個數,如果要送200個或2000個數,那豈不要寫上200條或2000條命令?這未免太笨了吧。為什么會出現這樣的狀況?是因為我們只會把地址寫在指令中,所以就沒辦法了,如果我們不是把地址直接寫在指令中,而是把地址放在另外一個寄存器單元中,根據這個寄存器單元中的數值決定該到哪個單元中取數據,比如,當前這個寄存器中的值是30H,那么就到30H單元中去取,如果是31H就到31H單元中去取,就能解決這個問題了。怎么個解決法呢?既然是看的寄存器中的值,那么我們就能通過一定的辦法讓這里面的值發生變化,比如取完一個數后,將這個寄存器單元中的值加1,還是執行同一條指令,可是取數的對象卻不一樣了,不是嗎。通過例程來說明吧。
MOV R7,#20
MOV R0,#30H
LOOP:MOV A,@R0
INC R0
DJNZ R7,LOOP
??? 這個例程中大部份指令我們是能看懂的,第一句,是將立即數20送到R7中,執行完后R7中的值應當是20。第二句是將立即數30H送入R0工作寄存器中,所以執行完后,R0單元中的值是30H,第三句,這是看一下R0單元中是什么值,把這個值作為地址,取這個地址單元的內容送入A中,此時,執行這條指令的結果就相當于MOV A,30H。第四句,沒學過,就是把R0中的值加1,因此執行完后,R0中的值就是31H,第五句,學過,將R7中的值減1,看是否等于0,不等于0,則轉到標號LOOP處繼續執行,因此,執行完這句后,將轉去執行MOV A,@R0這句話,此時相當于執行了MOV A,31H(因為此時的R0中的值已是31H了),如此,直到R7中的值逐次相減等于0,也就是循環20次為止,就實現了我們的要求:從30H單元開始將20個數據送入A中。
這也是一種尋找數據的辦法,由于數據是間接地被找到的,所以就稱之為間址尋址。注意,在間址尋址中,只能用R0或R1存放等尋找的數據。
指令系統
?
數據傳送指令
數據傳送指令包括數據的傳送、交換、堆棧數據的壓入與彈出,是最基本、使用率最高的一類指令。助記符有MOV、MOVX、MOVC、XCH、XCHD、SWAP、PUSH、POP共八種。
1.MOV類指令及功能(16條)
這類指令的功能是從源操作數到目的操作數的數據傳送。
MOV? A, Rn??? ;Rn→A,寄存器Rn的內容送到累加器A
MOV? A, direct?? ;(direct)→A,直接地址中的內容送A
MOV? A, @Ri??? ;(Ri)→A,Ri間址的內容送A
MOV? A, #data?? ;data→A,立即數送A
MOV? Rn,, A??? ;A→Rn,累加器A中的內容送寄存器Rn
MOV? Rn, direct?? ;(direct)→Rn;直接地址中的內容送Rn
MOV? Rn, #data?? ;data→Rn;立即數送Rn
MOV? direct, A?? ;A→(direct),A中的內容送入直接地址中
MOV? direct, Rn?? ;Rn→(direct),寄存器內容送入直接地址中
MOV? direct, direct? ;(direct) →(direct),源操作數直接地址的內容送入
;目的操作數的直接地址中
MOV? direct, @Ri? ;(Ri)→(direct),Ri間址內容送入直接地址中
MOV? direct, #data? ;data→(direct),立即數送入直接地址中
MOV? @Ri, A??? ;A→(Ri),A中內容送到Ri間址單元中
MOV? @Ri, direct? ;(direct)→(Ri),直接地址中內容送入Ri間址單元中
MOV? @Ri, #data?? ;data→(Ri),立即數送入Ri間址單元中
MOV? DPTR, #data16????? ;data16→DPTR,16位常數送入數據指針DPTR中,高8
;位送入DPH,低8位送入DPH,低8位送入DPL中
從上述指令可以看出目的操作數有A累加器、Rn寄存器、直接地址direct及間接地址@Ri,源操作數除此之外還多一種立即數data。
例1? R0中有常數30H,而30H地址中有常數50H
執行MOV A, R0后,A=30H,R0不變。
執行MOV A, @R0后A=50H,而不是30H,這條指令的功能是把R0中內容為地址的單元的書送入A,R0中是30H也就是把30H地址中內容50H送入A。
例2? 若(40H)=20H,(50H)=30H
執行MOV 40H, 50H; (50H) →(40H)
結果:(40H)=30H,50H地址中內容仍為30H。
例3? 若A=40H,R0=30H,
執行MOV @R0, A????????????? ;A→(R0)
結果:(30H)=40H,A與R0皆不變,即A=40H,R0=30H。
該指令功能是把A中內容送入R0間址單元即R0中內容為地址的單元。
例4? 執行MOV DPTR, #2040H????????? ;2040H→DPTR
結果:DPH=20H, DPL=40H
DPTR是片外RAM地址指針,只有這一條指令是傳送16位數據。
2.MOVC類指令及功能(2條)
MOVC A, @A+PC?????????????????? ;PC+1→PC, (A+PC) →A
MOVC A, @A+DPTR????????????????? ;(A+DPTR) →A
功能:該類屬于查表指令,利用這兩條指令很方便地查找放在程序存儲器中數據表格的內容。
例1? 程序
? 1000H MOV A, #10H?????? ;10H→A
? 1002H MOVC A, @A+PC?????? ;PC+1→PC,PC=1003H,(A+PC)=(10H+1003H)→A
? ...
? 1010H 02H
? 1011H 04H
? 1012H 06H
? 1013H 08H
程序執行結果:A=08H
用MOVC A, @A+PC指令需注意兩點:
1)指令中的PC是執行完本條指令后的PC值,即PC等于本條指令地址加1。
2)A是修正值,它等于查表指令和欲查數據相間隔字節數。A的范圍是0~255,一次該指令只能查找本指令后的256B范圍內的表格,故稱為近程查表。
例2? 程序
? 1000H MOV A, #01H???? ;01H→A
? 1002H MOV DPTR, #6000H??? ;6000H→DPTR
? 1005H MOVC A,@A+DPTR?? ;(A+DPTR)=(01H+6000H)=(6001H) →A
? ...
6001H 0AH
? 6002H 0BH
? 6003H 0CH
? 6004H 0DH
程序執行結果:A=0AH,查到了地址為6001H單元中的數據。
用MOVC A, @A+DPTR指令查表特點:A, DPTR都可以改變,因此可在64KB范圍內查表,故稱為遠程查表。這條指令更方便。
3.MOVX類指令(4條)
MOVX A, @DPTR???????? ;(DPTR) →A,DPTR間址單元內容送A
MOVX @DPTR, A???????? ;A→(DPTR), A 中內容送入DPTR間址單元
MOVX A, @Ri????????? ;(Ri) →A,Ri間址單元內容送A
MOVX @Ri, A????????? ;A→(Ri), A中內容送Ri間址單元
MOVX類指令功能:這四條指令專門用來與外部數據存儲區傳送數據。CPU與外部RAM傳送數據時只能用間接尋址方式。
例1? 把外部數據存儲單元2000H中的數據送到4000H單元中,設2000H中有數據30H。
?????? 程序???????????? 各條指令執行結果
??????? MOV DPTR, #2000H???????? ;2000H DPTR, DPTR=2000H
??????? MOVX A, @DPTR????????? ;(DPTR)? A即(2000) A,A=30H
??????? MOV DPTR, #4000H??????? ;4000H→DPTR, DPTR=4000H
??????? MOVX @DPTR, A????????? ;A→(DPTR)即A→(4000H), (4000H)=30H
例2? 把內部RAM50H單元數據送到片外20H單元,設50H中單元存有數據10H。
?????? 程序??????????????? 各條指令執行結果
??????? MOV A,50H????????????? ;(50H) 各條指令執行結果A, A=10H
??????? MOV R0,#20H????????? ;20H→R0, R0=20H
??????? MOVX @R0, A????????? ;A→(R0)即A→(20H)則20H=10H
注意:與外部RAM傳送數據時,地址小于256B用Ri間址,大于256B時用DPTR間址。
4.交換指令
?????? XCH A, Rn???????????? ;Rn A, Rn與A內容交換
?????? XCH A,direct??????????? ;(direct)? A, 直接地址內容與A內容交換
?????? XCH A, @Ri???????? ;(Ri)? A,Ri間址內容與A內容交換
?????? XCHD A, @Ri???????? ;(Ri.3~Ri.0) A.3~A.0, Ri間址內容低4
位與A中低4 位內容交換
?????? SWAP? A????????? ;A.3~A.0? A.7~A.4, A中高4位與低4位
交換
例? 若R0=30H, A=F0H, (30H)=46H
執行??? XCH A, R0?????????????? ;結果:A=30H,R0=F0H, R0與A 內容交換
?執行??? XCH A, @R0?????????????? ;結果:A=46H, (30H)=F0H, R0中不變,
;實際上是(R0) A即(30H) A
?若執行 XCHD A, @R0?????????????? ;結果:A=F6H,(30)H=40H
??????????????????? ;A與(30H)中低4位交換,高4位不變
? 執行 SWAP A???????????????? ;結果:A=0FH, 高低4位互換
5.堆棧操作指令(2條)
?PUSH、POP屬堆棧操作指令,其功能是把直接地址中的內容壓入堆棧保存,或從堆棧中取出(彈出)數據到直接地址中。
???????? PUSH direct???? ;SP+1→SP, (direct) →(SP)
???????????????? ;直接地址內容壓入堆棧頂
???????? POP? direct???? ;(SP)→(direct), SP-1→SP
???????????????? ;堆棧棧頂內容彈出到直接地址
?注意:堆棧是用戶自己設定的內部RAM中的一塊專用存儲區,使用堆棧時一定先設堆棧指針。堆棧遵循后進先出的原則安排數據。壓入數據時SP先加1,再壓入;彈出時,先彈出數據,SP再減1。
例? 設堆棧指針為30H,為保護現場把A和B中的內容壓入堆棧保護,然后根據需要再把兩者彈出。設A中為30H,B中為01H。
?????? 程序??????? 執行結果
??????? MOV?? SP, #30H? ;30H→SP, SP=30H設堆棧指針為30H
??????? PUSH? ACC??????? ;SP+1→SP=31H, A→(SP)即A→(31H),(31H)=30H
??????? PUSH? B??? ;SP+1→SP=32H, B→(SP)即B→(32H),(32H)=01H
??????? POP?? B??? ;SP→B即(32H)→B, B=01H, SP-1→SP=31H
??????? POP? ACC??? ;SP→A即(31H)→A, A=30H, SP-1→SP=30H
從此例可以看出壓入、彈出過程SP的變化規律
算術運算指令
算術運算指令的主要功能是實現算術加、減、乘、除等運算。
1.ADD類指令是不帶進位的加法運算指令(4條)。
ADD A,Rn????????? ;A+Rn→A, A與Rn寄存器內容相加,結果送到A中
ADD A,direct???????? ;(direct)+A→A, A與直接地址內容相加,和送A
ADD A, @Ri????? ;(Ri)+A→A, A與Ri間址內容相加,和送A
ADD A, #data???????? ;data+A→A, A與立即數相加,和送A
注意:ADD類指令相加結果均在A中,相加后源操作數不變。若A中最高位有進位,Cy置1;若半加位有進位,AC置1。A的結果還影響奇偶標志位P。
例? A=30H, R0=10H
執行? ADD A,R0? 結果:A=40H, R0=10H,標志位 P=1, Cy=0, OV=0, AC=0
2.ADDC類指令(帶進位加法4條)
ADDC A, Rn????? ;A+Rn+Cy→A,? A與R n內容、進位狀態相加,和送
到A中
ADDC A, direct???? ;(direct)+Cy+A→A, A與直接地址中內容、進位狀態
相加,和送A
ADDC A, @Ri????? ;(Ri)+Cy+A→A, A與Ri間址單元中內容、進位狀態
相加,和送A
?????? ADDC A, #data???????? ;data+Cy+A→A, A與 立即數、進位狀態相加,和送A
與ADD類指令的區別是,ADDC指令相加時連同進位標志Cy內容一起相加,主要用于多字節加法中的高位字節的相加,而最低位字節相加用ADD指令。進位位Cy加到字節的最低位。
例? 編寫計算1234H+0FE7H的程序,將結果存入內部RAM的41H和40H單元,40H存低8位,41H存高8位。
????? 程序
?????? MOV A, #34H?? ;被加數低8位數34H送A
?????? ADD A, #0E7H?? ;加數低8位數E7H與之相加,A=1BH,Cy=1
?????? MOV 40H, A?? ;A→40H即34H+E7H結果存入40H中(40H=1BH)
?????? MOV A, #12H?? ;被加數高8位數12H送A
?????? ADDC A, #0FH?? ;加數高8位0FH和Cy與A相加,A=22H
?????? MOV 41H, A?? ;高8位與進位位之和存入41H中(41H)=22H
?????????? ;總和為221BH,總結果在41H,40H單元中
3.SUBB類指令(4條)
?SUBB類指令是帶借位減法指令,其功能是將A中被減數減去源操作數指出的內容,再減去借位標志Cy(原進位標志)狀態,差值在A中。
SUBB A, Rn??? ;A-Rn-Cy→A ,A減寄存器Rn內容及進位標志
???? SUBB A, direct?? ;A-(direct)-Cy→A,A減直接地址內容和進位標志
???? SUBB A, Ri??? ;A-(Ri)-Cy→A, A減Ri間址單元內容和進位位標志
???? SUBB A, #data?? ;A-data-Cy→A, A減立即數和進位標志
說明:
1) 多字節減法時,低位相減有借位則把Cy置1,否則Cy為0。
2) MCS-51系列指令中沒有不帶借位的減法指令,所以在單字節或低位字節減法時用SUBB類指令前要先將Cy清0。
3)減去一個數實際上是加上這個數的相反數(負數),減法運算常常用補碼相加方式。
4.MUL(乘)和DIV(除)指令
?乘法指令只有一條:
MUL? AB????????? ;A×B→B和A,結果16位,高8位存入B,低8位在A中
?若乘積大于FFH則將溢出標志OV置1。
?除法指令也只有一條:
DIV? AB????????????? ; A÷B商→A,余數→B
?注意:當除數為0時結果不確定,則溢出將OV置1。
5.INC(加1)和DEC(減1)類指令
?加1類指令共5條,其功能是將操作數內容加1。
INC A???? ;A+1→A, A加1
INC?? Rn???????? ;Rn+1→Rn, Rn中內容加1
INC?? direct?????? ;(direct)+1→(direct), 直接地址中內容加1
INC @Ri??????? ;(Ri)+1→(Ri), Ri間址中的內容加1
INC?? DPTR??? ;DPTR+1→DPTR, 數據指針加1
例? 判斷INC R0和INC @R0兩條指令結果,比較兩者的區別。設R0=30H,(30H)=00H。
?執行? INC?? R0??????????? ;R0+1=30H+1→R0, 結果R0=31H
?執行? INC?? @R0?????????? ;(R0)+1=(30H)+1→(R0),結果(30H)=01H,R0中內
容不變,仍為30H
?減1類指令共4條,其功能是將操作數指定單元內容減1。
?????? DEC? A???? ;A-1→A, A中內容減1
?????? DEC? Rn???????? ;Rn-1→Rn, Rn中內容減1
?????? DEC? direct??? ;(direct)-1→(direct), 直接地址中內容減1
?????? DEC? @Ri???????? ;(Ri)-1→(Ri), Ri間址中的內容減1
?操作過程與加1指令類似,這里不再舉例。
6.十進制加法調整指令(1條)
?????? DA?? A
?功能:在加法指令后,把A中二進制碼自動調整成BCD碼。
例?? MOV? A, #05H?????? ;05H→A
?????? ADD? A, #08H?????? ;05H+08H→A=0DH
?????? DA?? A??????? ;結果調整A=13H,即是13的BCD碼
?注意:DA A指令只能跟在ADD或ADDC加法指令后,不適用于減法。
邏輯運算指令
1.ANL類指令(6條)
ANL類是邏輯與指令,其功能是將源操作數作數內容和目的操作數內容按位相“與”,結果存入目的操作數指定單元中,源操作數不變。
ANL A, Rn??????? ;A∩Rn→A
ANL A, direct?????? ;A∩(direct) →A
ANL A, @Ri?????? ;A∩(Ri) →A
ANL A, #data?????? ;A∩data→A
ANL direct, A?????? ;(direct)∩A→(direct)
ANL direct, #data????? ;(direct)∩data→(direct)
例? 設A=F6H,(30H)=0FH
執行? ANL A, 30H????????? ;A∩ (30H) →A
操作如下:
?11110110? (F6H)
∩? 00001111? (0FH)?? 注意:按位相“與”
??? 00000110? (06H)
結果:A=06H, 30H地址內容不變,即(30H)=0FH
若執行ANL 30H, A?????????? ;(30H)∩ A→(30H)
操作同上,結果放在30H地址中,A中內容不變,即(30H)=06H, A=F6H。
2.ORL類指令(6條)
ORL類指令是邏輯或指令,其功能是將源操作數作數內容和目的操作數內容按位邏輯“或”,結果存入目的操作數指定單元中,源操作數不變。
ORL A, Rn???? ;A∪Rn→A
ORL A,direct?????? ;A∪(direct) →A
?????? ORL A, @Ri??? ;A∪(Ri) →A
?????? ORL A, #data?????? ;A∪data→A
?????? ORL direct, A?????? ;(direct)∪A→(direct)
?????? ORL direct, #data????? ;(direct)∪data→(direct)
?“或”運算和“與”運算過程類似,這里不再舉例。
3.XRL類指令(6條)
?XRL類是異或指令,其功能是將兩個操作數指定內容按位“異或”,結果存于目的操作數指定單元中。“異或”原則是相同為“0”,相異為“1”。
XRL A, Rn??????? ;A⊕Rn→A
?????? XRL A, direct?????? ;A⊕(direct) →A
??????? XRL A, @Ri??? ;A⊕(Ri) →A
?????? XRL A, #data?????? ;A⊕data→A
?????? XRL direct, A?????? ;(direct)⊕A →(direct)
?????? XRL direct, #data?? ;(direct)⊕data→(direct)
例? (50H)=05H
?執行? XRL 50H, #06H???????????? ;(50H)⊕06H→(50H)
?操作如下:
???? 00000101 (05H)
⊕? 00000110 (06H)
??????? 00000011 (03H)
結果:(50H)=03H
4.循環移位指令(4條)
?循環移位指令的功能是將累加器A中內容循環位移或者和進位位一起移位。
例? A=01H, Cy=1
若執行一次? RRC? A后,結果為:A=10000000B? Cy=1
若執行一次? RLC? A后,結果為:A=00000011B? Cy=0
5.取反、清0指令
???? CPL? A????????????????? ;累加器內容按位取反。如果1就變0,如果0就變1
???? CLR? A????????????????? ;累加器A清0
控制轉移類指令
計算機運行過程中,有時因為操作的需要,程序不能按順序逐條執行指令,需要改變程序運行方向,即將程序跳轉到某個指定的地址再順序執行下去。
控制轉移類指令的功能就是根據要求修改程序計數器PC的內容,以改變程序運行方向,實現轉移。
控制轉移類指令可分為:無條件轉移、條件轉移、絕對轉移、相對轉移和調用、返回指令。下面我們將分類介紹。
1.無條件轉移指令(4條)
LJMP?? add16?????????? ;add16→PC,無條件跳轉到add16地址,可在64KB范圍內
轉移,稱為長轉移指令
AJMP?? add11????????? ;add11→PC,無條件轉向add11地址,在2KB范圍內轉移
SJMP?? rel?????????? ;PC+2+rel→PC,相對轉移,rel是偏移量,8 位有符號
數,范圍-128~127,即可向后跳轉128,向前可跳轉127
JMP??? @A+DPTR???????? ;A+DPTR→PC ,屬散轉指令,無條件轉向A與DPTR內容相
加后形成的新地址
例1? 執行指令
LJMP?? 9100H
不管這條指令存放在哪里,執行時將使程序轉移到9100H,和AJMP,SJMP指令是有差別的。
例2? 程序
2000H?? MOV?? R0 , #10H? ;10H→PC
2002H?? SJMP? 03H?? ;PC+2+rel=2002H+2+03H=2007H→PC
? ┇??????? ┇
2006H???? ┇
2007H???? ┇
? 從說明中可見,執行SJMP? 03H 指令后,馬上跳轉到2007H地址執行程序。
2.條件轉移指令(8條)
條件轉移指令是根據某種特定條件轉移的指令。條件滿足時轉移,條件不滿足時則順序
執行下面的指令。
JZ?? rel?????????? ;A=0轉向PC+2+rel→PC,A≠0順序執行
JNZ? rel?????????? ;A≠轉向PC+2+rel→PC ,A=0順序執行
CJNE A, direct, rel???? ;A≠ (direct)轉向PC+3+rel→PC且當A>(direct),Cy=0
;當A<(direct),Cy=1
;否則A=(direct),PC+3→PC即順序執行
CJNE A, #data, rel????? ;A data P轉向PC+3+rel→PC且當A >data,Cy=0
;當A ;A=data,PC+3→PC順序執行
CJNZ? Rn, #data, rel? ;Rn≠data轉向PC+3+rel→PC
;且當Rn>data,Cy=0,當Rn;Rn=data,PC+3→PC順序執行
CJNE? @Ri,#data, rel? ;(Ri) ≠data ,PC+3+rel→PC
;且當(Ri)>data ,Cy=0,當(Ri);(Ri)=data, PC+3→PC順序執行
DJNZ? Rn, rel?????? ;Rn-1→Rn ,Rn ≠0轉向PC+2+rel→PC
;Rn=0,PC+2→PC順序執行
DJNZ direct, rel????? ;(direct)-1→(direct),(direct) ≠0轉向 PC+2+rel
→PC
;(direct)=0 ,PC+2→PC順序執行
注意:
1)CJNE類指令借用進位標志Cy作為比較結果的標志位。從指令中可知,目的操作數內容小于原操作數內容Cy置1,反之Cy清0,該類指令多用于分支程序。
2) DJNZ指令執行時Rn或direct先減1,然后再判斷Rn或direct內容是否等于0。不為0則轉,為0順序執行。DJNZ用在循環程序中,控制循環次數很方便。
3) JZ和JNZ的操作數只有一個,是對A的內容的進行判斷的指令。
例1 以下程序的循環次數是多少,最后(R0)=?
MOV? R0 , #0
LL:???? ┇
DJNZ? R0 , LL
分析:由于DJNZ是減1再判斷大小的,因為R0=0,所以第一次執行DJNZ? R0 , LL后R0=FFH=255,則程序要執行的次數為256次,R0最后的值為0。
解:程序要循環的次數為256次,最后R0=0
3.調用、返回、控操作指令
在程序設計中,常常要把具有一定功能的公用程序編制成子程序。當主程序轉至子
程序時用調用指令,而在子程序的最后安排一條返回指令,使執行完子程序后再返回到主程序。
(1) LCALL??? addr16??? ;調用入口地址為addr16的子程序
這是一條長調指令,可調用64KB范圍內的子程序,因此,可放在程序的任何位置。
指令的執行過程分兩步:第一步把斷點(當前執行指令的下一條指令地址)壓入堆棧。第二步將調用的子程序的入口地址裝入PC。即addr16(16位地址)→PC,轉向執行子程序。
(2) ACALL??? addr11????? ;子程序入口地址為addr11的子程序
這是一條短調指令,只能實現2KB范圍內的子程序的調用。其指令執行過程與LCALL
指令一樣。但是需要注意的是:ACALL中addr11只占用PC的PC.0~PC.10位。
(3) RET???????? ;放在子程序最后,使程序準確返回到主程序斷點處
執行過程為:(SP)→PC.8~PC.15斷點地址高字節送入PC?
SP-1→SP,(SP) →PC.0~PC.7斷點低字節送入PC,
這時PC中為主程序斷點地址,程序準確返回到調用指令的下一條。
例? 設SP=62H,(62H)=07H,(61H)=30H,執行指令RET
結果:SP=60H,(PC)=0730H,CPU從0730H開始執行程序。
(4) RETI???? ;中斷返回指令
該指令用于中斷服務程序,使中斷程序結束后準確返回到主程序斷點處,執行過程同RET,它還能清除優先級狀態。
(5) NOP???????? ;空操作
執行該指令時,CPU只進行取指令、譯碼,而不進行任何操作,故稱為控操作。常用于產生一個機器周期延時。
位操作指令
MCS-51單片機的特色之一是具有很強的位處理功能。位操作指令又稱為布爾指令,其功能是對內部RAM中可進行位操作的區域進行位操作。
??? 在進行位操作時,位累加器C即進位標志Cy,位地址是片內RAM字節地址20H~2FH單元中連續的128個位(位地址00H~7FH)和部分功能寄存器。凡SFR中字符等地址能被8整除的特殊功能寄存器都具有可尋址的位地址,其中ACC(位地址E0H~E7H),B(位地址F0H~F7H)和片內RAM中128個位都可作軟件標志或存儲位變量。
1. 位數據傳送類指令(2條)
MOV?? C , bit????? ;(bit) →C,尋址位的狀態送入C
MOV?? bit , C????? ;C→(bit),C的狀態送入位地址中
2. 位修正指令(6條)
CLR? C??????? ;0→C, 清0累加器
CLR? bit??? ;0→(bit);清0尋址位
CPL? C??????? ;/C→C,取反
CPL? bit?????? ;(/bit) →(bit),尋址位取反
SETB?? C?????? ;1→C,C置1
SETB?? bit?????? ;1→ (bit),尋址位置1
3. 位邏輯運算指令(4條)
ANL? C , bit?? ;C∩(bit) →C,尋址位和C“與”,結果放在C
ANL? C , /bit????? ;C∩(/bit) →C,尋址位的非和C“與”,結果放在C
ORL? C , bit?? ;C∪(bit) →C,尋址位和C“或”,結果放在C
ORL? C , /bit????? ;C∪(bit) →C,尋址位和C的非“或”,結果放在C
4. 位條件轉移指令(5條)
JC?? rel??? ;C=1轉向PC+2+rel→PC
???????????????????????????????? C=0順序執行PC+2→PC
JNC? rel?????? ;C=0轉向PC+2+rel→PC
???????????????????????????????? C=1順序執行PC+2→PC
JB?? bit , rel???????? ;(bit) =1轉向PC+3+rel→PC
??????????????????????????????? (bit) =0順序執行PC+3→PC
JNB? bit , rel????? ;(bit) =0轉向PC+3+rel→PC
??????????????????????????????? (bit) =1順序執行PC+3→PC
JBC? bit , rel????? ;(bit) =1轉向PC+3+rel→PC;同時0→(bit)
???????????????????????????????????? (bit) =0順序執行PC+3→PC
注意:JBC與JB指令區別,前者轉移后并把尋址位清0,后者只轉移不清0尋址位。
例1 設P1為輸入口,P3.0作輸出線,執行下列指令:
MOV?? C , P1.0?????? ;(P1.0) →C
ANL?? C , P1.1?????? ;(C)∩(P1.1) →C
ANL?? C , /P1.32?? ;(C)∩(/P1.2) →C
MOV?? P3.0 , C??????? ;C→P3.0?
結果是:P3.0=(P1.0) ∩(P1.1) ∩(/P1.2)
例2? 用位操作指令編程計算邏輯方程
???????? P1.5=ACC.0 ∩ (B.0∪P1.2) ∪P1.3
解:???? MOV? C , B.0?????? ;B.0→C
ORL? C , P1.2?????? ;C∪P1.2→C? 即B.0+P1.2→C
ANL? C , ACC.0? ;C∩ACC.0→C? 即ACC.0∩(B.0∪P1.2)→C
ORL? C , P1.3?????? ;C∪P1.3→C 即 ACC.0∩(B.0∪P1.2)∪P1.3→C
MOV? P1.5 , C?????? ;C→P1.5
評論
查看更多