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