<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 什么是單片機(jī)尋址方式與指令系統(tǒng)

          什么是單片機(jī)尋址方式與指令系統(tǒng)

          作者: 時間:2011-10-09 來源:網(wǎng)絡(luò) 收藏

          通過前面的學(xué)習(xí),我們已經(jīng)了解了內(nèi)部的結(jié)構(gòu),并且也已經(jīng)知道,要控制,讓它為我們干學(xué),要用指令,我們已學(xué)了幾條指令,但很零散,從現(xiàn)在開始,我們將要系統(tǒng)地學(xué)習(xí)8051的指令部份。

          一、概述

          1、指令的格式

          指令的一個重要組成部分是操作數(shù),由它指定參與運(yùn)算的數(shù)據(jù)或數(shù)據(jù)所在的存儲器單元或寄存器或I/O接口的地址。指令中所規(guī)定的尋找操作數(shù)的方式就是。每一種計(jì)算都具有多種,尋址方式越多,計(jì)算機(jī)的功能就越強(qiáng),靈活性就越大。尋址方式的多少及尋址功能是反映優(yōu)劣的主要因素之一。要掌握也可從尋址方式入手。

          MCS-51的尋址方式有7種:立即尋址(#data)、寄存器尋址(Rn)、間接尋址(@Ri、@DPTR)直接尋址direct、變址尋址(A+)、相對尋址(rel)和特定寄存器尋址(A)。有些書把A當(dāng)寄存器尋址,把位尋址單獨(dú)作一種尋址方式,不管怎么分類其目的是為了便于記憶、掌握111條指令。

          1.立即尋址(#data)

          操作數(shù)包含在指令字節(jié)中,操作數(shù)直接出現(xiàn)在指令中,并存放在程序存儲器中,這種方式稱為立即尋址。

          立即尋址指令的操作數(shù)是一個8位或16位的二進(jìn)制常數(shù),它前面以“#”號標(biāo)識,例如:ADD A,#56H,即#56H與累加器A(設(shè)為31H)內(nèi)容相加,結(jié)果(87H)存于累加器A中。這條指令的機(jī)器碼為2456H.

          2.寄存器尋址(Rn)

          由指令指出某一個寄存器中的內(nèi)容作為操作數(shù),這種尋址方式稱為寄存器尋址。在這種尋址方式中,指令的操作碼中包含了參加操作的工作寄存器R0~R7的代碼(指令操作碼字節(jié)的低3位指明所尋址的工作寄存器)。例如:ADD A,Rn中的Rn,當(dāng)n為0、1、2時,機(jī)器碼分別為28、29、2A.

          3.間接尋址(@Ri/@DPTR)

          由指令指出某一個寄存器內(nèi)容作為操作數(shù)的地址。這種尋址方式稱為寄存器間接尋址。訪問外部RAM時,可使用R0,R1或DPTR作為地址指針,寄存器間接尋址用符號“@”表示。

          例如:MOV A,@RO(機(jī)器碼E7)是指:若RO內(nèi)容為66(內(nèi)部RAM地址單元66H),而66H單元中內(nèi)容是27H,則指令的功能是將27H這個數(shù)送到累加器A.

          4.直接尋址(direct)

          在指令中直接給出操作數(shù)所在存儲單元的地址(一個8位二進(jìn)制數(shù)),稱為直接尋址。直接地址用direct表示,

          直接尋址方式中操作數(shù)存儲的空間有三種:

          (1).內(nèi)部數(shù)據(jù)存儲器的128個字節(jié)單元(00H~7FH)

          (2).位地址空間(有些書把這種尋址方式單獨(dú)作一種尋址方式)

          (3).特殊功能寄存器, 特殊功能寄存器只能用直接尋址方式進(jìn)行訪問。

          5.基址加變址尋址(@A+PC/@A+DPTR)

          以16位寄存器(DPTR或PC)作為基址寄存器,加上地址偏移量(累加器A中的8位無符號數(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.相對尋址(rel)

          以程序計(jì)數(shù)器PC的當(dāng)前值為基址,加上相對尋址指令的字節(jié)長度,再加上指令中給定的偏移量rel的值(rel是一個8位帶符號數(shù),用二進(jìn)制補(bǔ)碼表示),形成相對尋址的地址。

          例如指令:

          JNZ rel (或rel = 23H,機(jī)器碼為7023)
          當(dāng)A≠0時,程序跳到這條指令后面,相差23個字節(jié)運(yùn)行下一條指令。

          7.特定寄存器尋址

          累加器A和數(shù)據(jù)針DPTR這兩個使用最頻繁的寄存器又稱為特殊寄存器。對特定寄存器的操作指令,指令不再需要指出其地址字節(jié),指令碼本身隱含了操作對象A或DPTR。

          例如:

          INC A (指令碼04) ;累加器加1

          MOV A,#12H (指令碼7412) ;數(shù)12送累加器

          INC DPTR (指令碼A3) ;數(shù)據(jù)指針內(nèi)容加1

          綜上所述,尋址方式與存儲器結(jié)構(gòu)有密切關(guān)系。一種尋址方式只適合于對一部分存儲器進(jìn)行操作,在使用時要加以注意。

          我們已知,要讓計(jì)算機(jī)做事,就得給計(jì)算機(jī)以指令,并且我們已知,計(jì)算機(jī)很“笨”,只能懂得數(shù)字,如前面我們寫進(jìn)機(jī)器的75H,90H,00H等等,所以指令的第一種格式就是機(jī)器碼格式,也說是數(shù)字的形式。但這種形式實(shí)在是為難我們?nèi)肆耍y記了,于是有另一種格式,助記符格式,如MOV P1,#0FFH,這樣就好記了。 這兩種格式之間的關(guān)系呢,我們不難理解,本質(zhì)上它們完全等價,只是形式不一樣而已。

          2、匯編

          我們寫指令使用匯編格式,而計(jì)算機(jī)和單片機(jī)只懂機(jī)器碼格式,所以要將我們寫的匯編格式的指令轉(zhuǎn)換為機(jī)器碼格式,這種轉(zhuǎn)換有兩種辦法:手工匯編和機(jī)器匯編。手工匯編實(shí)際上就是查表,因?yàn)檫@兩種格式純粹是格式不一樣,所以是一一對應(yīng)的,查一張表格就行了。不過手工查表總是嫌麻煩,所以就有了計(jì)算機(jī)軟件,用計(jì)算機(jī)軟件來替代手工查表,這就是機(jī)器匯編。

          二、單片機(jī)的尋址

          讓我們先來復(fù)習(xí)一下我們學(xué)過的一些指令:MOV P1,#0FFH,MOV R7,#0FFH這些指令都是將一些數(shù)據(jù)送到對應(yīng)的位置中去,為什么要送數(shù)據(jù)呢?第一個因?yàn)樗腿氲臄?shù)能讓燈全滅掉,第二個是為了要實(shí)現(xiàn)延時,從這里我們能看出來,在用單片機(jī)的編程語言編程時,經(jīng)常要用到數(shù)據(jù)的傳遞,事實(shí)上數(shù)據(jù)傳遞是單片機(jī)編程時的一項(xiàng)重要工作,一共有28條指令(單片機(jī)共111條指令)。下面我們就從數(shù)據(jù)傳遞類指令開始吧。

          分析一下MOV P1,#0FFH這條指令,我們不難得出結(jié)論,第一個詞MOV是命令動詞,也就是決定做什么事情的,MOV是MOVE少寫了一個E,所以就是“傳遞”,這就是指令,規(guī)定做什么事情,后面還有一些參數(shù),分析一下,數(shù)據(jù)傳遞必須要有一個“源”也就是你要送什么數(shù),必須要有一個“目的”,也就是你這個數(shù)要送到什么地方去,顯然在上面那條單片機(jī)指令中,要送的數(shù)(源)就是0FFH,而要送達(dá)的地方(目的地)就是P1這個寄存器。在數(shù)據(jù)傳遞類指令中,均將目的地寫在指令的后面,而將源寫在最后。

          這條指令中,送給P1是這個數(shù)本身,換言之,做完這條指令后,我們能明確地知道,P1中的值是0FFH,但是并不是任何時候都能直接給出數(shù)本身的。例如,在我們前面給出的單片機(jī)延時程序例是這樣寫的:

          MAIN: SETB P1.0    ?。唬ǎ保?/P>

             LCALL DELAY ;(2)

              CLR P1.0      ;(3)

             LCALL DELAY  ??;(4)

              AJMP MAIN   ?。唬ǎ担?/P>

          ;以下子程序

          DELAY: MOV R7,#250  ?。唬ǎ叮?/P>

          D1: MOV R6,#250  ?。唬ǎ罚?/P>

          D2: DJNZ R6,D2   ??;(8)

             DJNZ R7,D1  ?。唬ǎ梗?/P>

             RET       ?。唬ǎ保埃?/P>

             END       ?。唬ǎ保保?

          表1

          -----------------------------------------------------

          MAIN: SETB P1.0    ?。唬ǎ保?/P>

             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   ?。唬ǎ福?/P>

             DJNZ R7,D1   ;(9)

             RET        ;(10)

             END        ;(11)

          表2

           這樣一來,我每次調(diào)用延時程序延時的時間都是相同的(大致都是0.13S),如果我提出這樣的要求:燈亮后延時時間為0.13S燈滅,燈滅后延時0.1秒燈亮,如此循環(huán),這樣的程序還能滿足要求嗎?不能,怎么辦?我們能把延時程序改成這樣(見表2):調(diào)用則見表2中的主程,也就是先把一個數(shù)送入30H,在子程序中R7中的值并不固定,而是根據(jù)30H單元中傳過來的數(shù)確定。這樣就能滿足要求。

          從這里我們能得出結(jié)論,在數(shù)據(jù)傳遞中要找到被傳遞的數(shù),很多時候,這個數(shù)并不能直接給出,需要變化,這就引出了一個概念:如何尋找操作數(shù),我們把尋找操作數(shù)所在單元的地址稱之為尋址。在這里我們直接使用數(shù)所在單元的地址找到了操作數(shù),所以稱這種辦法為直接尋址。除了這種辦法之外,還有一種,如果我們把數(shù)放在工作寄存器中,從工作寄存器中尋找數(shù)據(jù),則稱之為寄存器尋址。例:MOV A,R0就是將R0工作寄存器中的數(shù)據(jù)送到累加器A中去。提一個問題:我們知道,工作寄存器就是內(nèi)存單元的一部份,如果我們選擇工作寄存器組0,則R0就是RAM的00H單元,那么這樣一來,MOV A,00H,和MOV A,R0不就沒什么區(qū)別了嗎?為什么要加以區(qū)別呢?的確,這兩條指令執(zhí)行的結(jié)果是完全相同的,都是將00H單元中的內(nèi)容送到A中去,但是執(zhí)行的過程不一樣,執(zhí)行第一條指令需要2個周期,而第二條則只需要1個周期,第一條指令變成最終的目標(biāo)碼要兩個字節(jié)(E5H 00H),而第二條則只要一個字節(jié)(E8h)就能了。

          這么斤斤計(jì)較!不就差了一個周期嗎,如果是12M的晶體震蕩器的話,也就1個微秒時間了,一個字節(jié)又能有多少?

          不對,如果這條指令只執(zhí)行一次,也許無所謂,但一條指令如果執(zhí)行上1000次,就是1毫秒,如果要執(zhí)行1000000萬次,就是1S的誤差,這就很可觀了,單片機(jī)做的是實(shí)時控制的事,所以必須如此“斤斤計(jì)較”。字節(jié)數(shù)同樣如此。

          再來提一個問題,現(xiàn)在我們已知,尋找操作數(shù)能通過直接給的方式(立即尋址)和直接給出數(shù)所在單元地址的方式(直接尋址),這就夠了嗎?

          看這個問題,要求從30H單元開始,取20個數(shù),分別送入A累加器。

          就我們目前掌握的辦法而言,要從30H單元取數(shù),就用MOV A,30H,那么下一個數(shù)呢?是31H單元的,怎么取呢?還是只能用MOV A,31H,那么20個數(shù),不是得20條指令才能寫完嗎?這里只有20個數(shù),如果要送200個或2000個數(shù),那豈不要寫上200條或2000條命令?這未免太笨了吧。為什么會出現(xiàn)這樣的狀況?是因?yàn)槲覀冎粫训刂穼懺谥噶钪校跃蜎]辦法了,如果我們不是把地址直接寫在指令中,而是把地址放在另外一個寄存器單元中,根據(jù)這個寄存器單元中的數(shù)值決定該到哪個單元中取數(shù)據(jù),比如,當(dāng)前這個寄存器中的值是30H,那么就到30H單元中去取,如果是31H就到31H單元中去取,就能解決這個問題了。怎么個解決法呢?既然是看的寄存器中的值,那么我們就能通過一定的辦法讓這里面的值發(fā)生變化,比如取完一個數(shù)后,將這個寄存器單元中的值加1,還是執(zhí)行同一條指令,可是取數(shù)的對象卻不一樣了,不是嗎。通過例程來說明吧。

          MOV R7,#20

             MOV R0,#30H

          LOOP:MOV A,@R0

             INC R0

             DJNZ R7,LOOP

          這個例程中大部份指令我們是能看懂的,第一句,是將立即數(shù)20送到R7中,執(zhí)行完后R7中的值應(yīng)當(dāng)是20。第二句是將立即數(shù)30H送入R0工作寄存器中,所以執(zhí)行完后,R0單元中的值是30H,第三句,這是看一下R0單元中是什么值,把這個值作為地址,取這個地址單元的內(nèi)容送入A中,此時,執(zhí)行這條指令的結(jié)果就相當(dāng)于MOV A,30H。第四句,沒學(xué)過,就是把R0中的值加1,因此執(zhí)行完后,R0中的值就是31H,第五句,學(xué)過,將R7中的值減1,看是否等于0,不等于0,則轉(zhuǎn)到標(biāo)號LOOP處繼續(xù)執(zhí)行,因此,執(zhí)行完這句后,將轉(zhuǎn)去執(zhí)行MOV A,@R0這句話,此時相當(dāng)于執(zhí)行了MOV A,31H(因?yàn)榇藭r的R0中的值已是31H了),如此,直到R7中的值逐次相減等于0,也就是循環(huán)20次為止,就實(shí)現(xiàn)了我們的要求:從30H單元開始將20個數(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
          功能:該類屬于查表指令,利用這兩條指令很方便地查找放在程序存儲器中數(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類指令功能:這四條指令專門用來與外部數(shù)據(jù)存儲區(qū)傳送數(shù)據(jù)。CPU與外部RAM傳送數(shù)據(jù)時只能用間接尋址方式。
          例1 把外部數(shù)據(jù)存儲單元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ù)時,地址小于256B用Ri間址,大于256B時用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中的一塊專用存儲區(qū),使用堆棧時一定先設(shè)堆棧指針。堆棧遵循后進(jìn)先出的原則安排數(shù)據(jù)。壓入數(shù)據(jù)時SP先加1,再壓入;彈出時,先彈出數(shù)據(jù),SP再減1。
          例 設(shè)堆棧指針為30H,為保護(hù)現(xiàn)場把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
          從此例可以看出壓入、彈出過程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指令相加時連同進(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)志
          說明:
          1) 多字節(jié)減法時,低位相減有借位則把Cy置1,否則Cy為0。
          2) MCS-51系列指令中沒有不帶借位的減法指令,所以在單字節(jié)或低位字節(jié)減法時用SUBB類指令前要先將Cy清0。
          3)減去一個數(shù)實(shí)際上是加上這個數(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時結(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
          操作過程與加1指令類似,這里不再舉例。
          6.十進(jìn)制加法調(diào)整指令(1條)
          DA A
          功能:在加法指令后,把A中二進(jìn)制碼自動調(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)算過程類似,這里不再舉例。
          3.XRL類指令(6條)
          XRL類是異或指令,其功能是將兩個操作數(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)行過程中,有時因?yàn)椴僮鞯男枰?,程序不能按順序逐條執(zhí)行指令,需要改變程序運(yùn)行方向,即將程序跳轉(zhuǎn)到某個指定的地址再順序執(zhí)行下去。
          控制轉(zhuǎn)移類指令的功能就是根據(jù)要求修改程序計(jì)數(shù)器PC的內(nèi)容,以改變程序運(yùn)行方向,實(shí)現(xiàn)轉(zhuǎn)移。
          控制轉(zhuǎn)移類指令可分為:無條件轉(zhuǎn)移、條件轉(zhuǎn)移、絕對轉(zhuǎn)移、相對轉(zhuǎn)移和調(diào)用、返回指令。下面我們將分類介紹。
          1.無條件轉(zhuǎn)移指令(4條)
          LJMP add16 ;add16→PC,無條件跳轉(zhuǎn)到add16地址,可在64KB范圍內(nèi)
          轉(zhuǎn)移,稱為長轉(zhuǎn)移指令
          AJMP add11 ;add11→PC,無條件轉(zhuǎn)向add11地址,在2KB范圍內(nèi)轉(zhuǎn)移
          SJMP rel ;PC+2+rel→PC,相對轉(zhuǎn)移,rel是偏移量,8 位有符號
          數(shù),范圍-128~127,即可向后跳轉(zhuǎn)128,向前可跳轉(zhuǎn)127
          JMP @A+DPTR ;A+DPTR→PC ,屬散轉(zhuǎn)指令,無條件轉(zhuǎn)向A與DPTR內(nèi)容相
          加后形成的新地址
          例1 執(zhí)行指令
          LJMP 9100H
          不管這條指令存放在哪里,執(zhí)行時將使程序轉(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 ┇
          從說明中可見,執(zhí)行SJMP 03H 指令后,馬上跳轉(zhuǎn)到2007H地址執(zhí)行程序。
          2.條件轉(zhuǎn)移指令(8條)
          條件轉(zhuǎn)移指令是根據(jù)某種特定條件轉(zhuǎn)移的指令。條件滿足時轉(zhuǎn)移,條件不滿足時則順序
          執(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 data,Cy=1,
          ;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)Rndata,Cy=1
          ;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)data,Cy=1
          ;(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í)行時Rn或direct先減1,然后再判斷Rn或direct內(nèi)容是否等于0。不為0則轉(zhuǎn),為0順序執(zhí)行。DJNZ用在循環(huán)程序中,控制循環(huán)次數(shù)很方便。
          3) JZ和JNZ的操作數(shù)只有一個,是對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)至子
          程序時用調(diào)用指令,而在子程序的最后安排一條返回指令,使執(zhí)行完子程序后再返回到主程序。
          (1) LCALL addr16 ;調(diào)用入口地址為addr16的子程序
          這是一條長調(diào)指令,可調(diào)用64KB范圍內(nèi)的子程序,因此,可放在程序的任何位置。
          指令的執(zhí)行過程分兩步:第一步把斷點(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í)行過程與LCALL
          指令一樣。但是需要注意的是:ACALL中addr11只占用PC的PC.0~PC.10位。
          (3) RET ;放在子程序最后,使程序準(zhǔn)確返回到主程序斷點(diǎn)處
          執(zhí)行過程為:(SP)→PC.8~PC.15斷點(diǎn)地址高字節(jié)送入PC
          SP-1→SP,(SP) →PC.0~PC.7斷點(diǎn)低字節(jié)送入PC,
          這時PC中為主程序斷點(diǎn)地址,程序準(zhǔn)確返回到調(diào)用指令的下一條。
          例 設(shè)SP=62H,(62H)=07H,(61H)=30H,執(zhí)行指令RET
          結(jié)果:SP=60H,(PC)=0730H,CPU從0730H開始執(zhí)行程序。
          (4) RETI ;中斷返回指令
          該指令用于中斷服務(wù)程序,使中斷程序結(jié)束后準(zhǔn)確返回到主程序斷點(diǎn)處,執(zhí)行過程同RET,它還能清除優(yōu)先級狀態(tài)。
          (5) NOP ;空操作
          執(zhí)行該指令時,CPU只進(jìn)行取指令、譯碼,而不進(jìn)行任何操作,故稱為控操作。常用于產(chǎn)生一個機(jī)器周期延時。

          位操作指令

          MCS-51單片機(jī)的特色之一是具有很強(qiáng)的位處理功能。位操作指令又稱為布爾指令,其功能是對內(nèi)部RAM中可進(jìn)行位操作的區(qū)域進(jìn)行位操作。
          在進(jìn)行位操作時,位累加器C即進(jìn)位標(biāo)志Cy,位地址是片內(nèi)RAM字節(jié)地址20H~2FH單元中連續(xù)的128個位(位地址00H~7FH)和部分功能寄存器。凡SFR中字符等地址能被8整除的特殊功能寄存器都具有可尋址的位地址,其中ACC(位地址E0H~E7H),B(位地址F0H~F7H)和片內(nèi)RAM中128個位都可作軟件標(biāo)志或存儲位變量。
          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;同時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



          評論


          相關(guān)推薦

          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();