《新編單片機原理與應用》課件第3章_第1頁
《新編單片機原理與應用》課件第3章_第2頁
《新編單片機原理與應用》課件第3章_第3頁
《新編單片機原理與應用》課件第3章_第4頁
《新編單片機原理與應用》課件第3章_第5頁
已閱讀5頁,還剩260頁未讀 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領

文檔簡介

第3章MCS-51指令系統(tǒng)3.1MCS-51指令系統(tǒng)3.2匯編語言程序結(jié)構(gòu)3.3并行多任務程序結(jié)構(gòu)及實現(xiàn)3.4實用程序舉例指令、指令系統(tǒng)等基本概念以及MCS-51系列單片機CPU支持的七種尋址方式已在第1章中介紹過,這里不再重復。本章只介紹MCS-51系列單片機指令系統(tǒng)及其匯編語言程序設計的一些基本概念及注意事項。

MCS-51系列單片機采用復雜指令系統(tǒng),共有42種操作碼助記符,支持直接尋址、寄存器尋址、間接尋址、立即數(shù)尋址、變址尋址、相對尋址、位尋址等七種尋址方式。不同指令操作碼助記符與不同尋址方式之間的組合就構(gòu)成了MCS-51系列單片機的指令系統(tǒng),共111條。按功能可將這些指令分成數(shù)據(jù)傳送、算術運算、邏輯運算、控制轉(zhuǎn)移、位操作等五大類,每一類型的指令中又包含若干條指令。這使許多初學者無所適從,3.1MCS-51指令系統(tǒng)感到很難掌握,其實只要理解每類指令的功能、助記符及其支持的尋址方式,即可從MCS-51指令表中找出完成特定操作所需的指令。

本章在介紹MCS-51指令系統(tǒng)時,為了方便敘述,使用下列符號及約定:

(1)

Rn(n

=

0~7):表示工作寄存器組R7~R0中的某一寄存器。

(2)

@Ri(i

=

0~1):以寄存器R0或R1作間接尋址,表示操作數(shù)地址在寄存器R0或R1中,而“@”是間接尋址標識符。操作對象是外部RAM或內(nèi)部RAM00~FFH單元(對僅有前128字節(jié)內(nèi)部RAM的51子系列來說,地址范圍是00~7FH)。

(3)

@DPTR:以數(shù)據(jù)指針DPTR(16位)作間接尋址,操作數(shù)在外部RAM中,“@”同樣是間接尋址標識符。

(4)

#data:8位立即數(shù);#data16:16位立即數(shù)。其中“#”是立即數(shù)標識符,常用于初始化內(nèi)部RAM單元、特殊功能寄存器、數(shù)據(jù)指針DPTR。

(5)

direct:8位直接地址,可以是內(nèi)部RAM00~7FH單元字節(jié)地址、內(nèi)部RAM20H~2FH單元中的位地址或特殊功能寄存器的映象地址。

(6)

/bit:在位操作中,取出“bit”位信息后,先取反,然后再參與運算,但不改變bit位的值,其中“

/

”是位取反標識符。

(7)

rel:補碼形式的8位偏移地址,范圍在-128~+127。

(8)

rrr:在操作碼中,用于表示R7~R0寄存器的編碼,rrr編碼與寄存器R7~R0之間對應關系如下:

rrr的編碼(二進制)對應的工作寄存器名

000 R0

001 R1

010 R2

011R3

100 R4

101R5

110R6

111 R7

(9)

addr11:11位目標地址,用于ACALL(絕對調(diào)用)和AJMP(絕對跳轉(zhuǎn))指令中,轉(zhuǎn)移范圍為2KB。

(10)

addr16:16位目標地址,用于LCALL和LJMP指令中,轉(zhuǎn)移范圍為64KB。

(11)操作數(shù)中的累加器A寫作“A”時,是寄存器尋址;寫作“Acc”時是直接尋址,盡管操作對象均是CPU內(nèi)的累加器A。對于支持直接尋址和寄存器尋址的指令來說,用A和Acc均可,只是指令的操作碼不同;對于不支持寄存器尋址的指令(如PUSH、POP),則不能將累加器Acc寫作“A”;而對于不支持直接尋址的指令,如“MOVX”中的“A”也不能寫成“Acc”。因此,在匯編語言指令中,須嚴格區(qū)分累加器A的寫法。

(12)累加器A內(nèi)容為nn時,用“A=nn”表示;地址編碼為mm的存儲單元內(nèi)容用“(mm)”表示。

(13)指令執(zhí)行時間用“機器周期”度量。例如“MOVA,Rn”指令執(zhí)行時間為一個機器周期,在標準MCS-51中,一個機器周期包含12個振蕩(即時鐘)周期。如果晶振頻率為12MHz,則振蕩周期T

=

1/12μs,因此一個機器周期為12T,即1μs;對于運行在“6時鐘/機器周期”的8×C5××2、89C51RX、P89C6××2芯片來說,指令機器周期數(shù)不變,但指令執(zhí)行時間縮短了一半;又如對于“2時鐘/機器周期”芯片LPC900系列來說,指令執(zhí)行時間只有標準MCS-51的1/6。

(14)指令機器碼一律用二進制書寫。

(15)對于不常用或約束條件多、容易出錯的指令,在指令表中加灰色背景,程序設計時應盡量避免使用這類指令。3.1.1數(shù)據(jù)傳送指令

數(shù)據(jù)傳送是計算機系統(tǒng)中最常見,也是最基本的操作。因此,數(shù)據(jù)傳送指令在計算機指令系統(tǒng)中占有重要位置,指令條數(shù)也最多,其任務是實現(xiàn)計算機系統(tǒng)內(nèi)不同存儲單元之間的信息傳送,如圖3-1所示。

圖3-1MCS-51中不同存儲區(qū)之間數(shù)據(jù)傳送示意圖在MCS-51指令系統(tǒng)中,數(shù)據(jù)傳送指令包括:

(1)內(nèi)部RAM、特殊功能寄存器之間的數(shù)據(jù)傳送,這類指令用“MOV”作為指令操作碼助記符。

(2)外部RAM(包括擴展的并行I/O口、內(nèi)部擴展RAM)與累加器A之間的數(shù)據(jù)傳送,這類指令用“MOVX”作為指令操作碼助記符。

(3)程序存儲器讀指令,即程序存儲器ROM與累加器A之間數(shù)據(jù)指令,這類指令用“MOVC”作為指令操作碼助記符。

(4)堆棧操作指令。

(5)字節(jié)交換指令。數(shù)據(jù)傳送指令一般不影響程序狀態(tài)字寄存器PSW中的標志位,只有當數(shù)據(jù)傳送到累加器A時,PSW中的奇偶標志位P會改變,原因是奇偶標志位P總是體現(xiàn)累加器A中“1”的個數(shù)的奇偶性。

當累加器Acc為0時,Z(零)標志置1;反之Z標志清0。因此當目的操作數(shù)為累加器Acc時,數(shù)據(jù)傳送指令會影響Z標志。

1.內(nèi)部RAM、特殊功能寄存器之間的數(shù)據(jù)傳送

MCS-51內(nèi)部RAM和特殊功能寄存器之間數(shù)據(jù)傳送指令匯編語言格式、機器碼以及執(zhí)行時間如表3-1所示。

表3-1內(nèi)部RAM與特殊功能寄存器之間的數(shù)據(jù)傳送指令續(xù)表由表3-1可見:

(1)前128字節(jié)內(nèi)部RAM(即00H~7FH)各單元之間,以及特殊功能寄存器(地址分散在80H~0FFH之間)可以直接傳送,不一定要經(jīng)過累加器A,例如:

MOV32H,90H ;

將特殊功能寄存器90H單元中的(即P1口)內(nèi)容送內(nèi)部RAM32H單元中,

;該指令中目的操作數(shù)(內(nèi)部RAM)、源操作數(shù)(特殊功能寄存器90H單元)

;均使用了直接尋址方式

MOV32H,43H ;將內(nèi)部RAM43H單元內(nèi)容送內(nèi)部RAM32H單元中。

MOVP1,B ;將寄存器B內(nèi)容送P1口鎖存器中

(2)

MCS-51指令系統(tǒng)約定:對于特殊功能寄存器,只能用直接尋址方式訪問;對于高128字節(jié)內(nèi)部只能用寄存器間接尋址方式。因此,在直接尋址方式中,當直接地址在80H~0FFH之間時,操作對象是特殊功能寄存器,而不是內(nèi)部RAM高128字節(jié)。對于地址編碼在80H~0FFH之間的內(nèi)部RAM,只能通過寄存器間接尋址訪問,例如:

MOV@R0,B ;假設該指令執(zhí)行前,R0內(nèi)容為90H,則該指令的含義是將特殊功能寄存

;器B(地址為0F0H)內(nèi)容送內(nèi)部RAM的90H單元中

(3)對于低128字節(jié)內(nèi)部RAM,可以用直接尋址方式,也可以用寄存器間接尋址方式,例如:

MOV32H,#23H ;將立即數(shù)23H傳送內(nèi)部RAM的32H單元中,目的操作數(shù)使用了直接尋

;址方式

MOV@R0,#23H ;假設該指令執(zhí)行前,R0中的內(nèi)容為32H,則該指令的作用與上條指令相

;同,也是將立即數(shù)23H傳送到內(nèi)部RAM的32H單元中,只是目的操作

;數(shù)采用寄存器間接尋址方式

(4)對于特殊功能寄存器,在指令中無論是引用寄存器名,還是直接給出寄存器映象地址,結(jié)果都一樣,只是書寫形式不同而已。匯編時匯編程序自動將寄存器名替換為對應的映象地址,如“MOVP1,#23H”與“MOV90H,#23H”完全等價。

(5)盡管寄存器B是CPU內(nèi)寄存器,但MCS-51指令系統(tǒng)沒有提供B寄存器的寄存器尋址方式(只有乘法指令例外),例如“MOVB,A”指令中目的操作數(shù)的尋址方式是直接尋址方式,并不是寄存器尋址方式。

(6)在同一指令中,只允許其中一個操作數(shù)使用寄存器間接尋址方式,因而“MOV@R0,@R1”指令不存在。

也正因如此,內(nèi)部RAM高128字節(jié)之間不能直接傳送,必須通過累加器A或內(nèi)部RAM作為中介,例如將內(nèi)部RAM的82H單元傳送到內(nèi)部RAM的8FH單元時,可用如下指令實現(xiàn):

MOVR0,#82H

MOVA,@R0

MOVR0,#8FH

MOV@R0,A

例3.1

在仿真機上,用單步方式執(zhí)行下列指令,并觀察指令執(zhí)行前后,內(nèi)部RAM有關單元內(nèi)容和程序狀態(tài)字PSW中Cy、Ac、OV、P等標志位的變化,了解數(shù)據(jù)傳送指令對標志位的影響。

MOV30H,#01H ;把立即數(shù)01H傳送到內(nèi)部RAM30H單元

MOVA,30H ;該指令執(zhí)行后累加器A內(nèi)容為01H,含有奇數(shù)個“1”,因此P標志位為1

MOVA,#03H ;該指令執(zhí)行后累加器A內(nèi)容為03H,含有偶數(shù)個“1”,因此P標志位為0

MOV30H,#07H ;執(zhí)行后,30H單元內(nèi)容也是07H,但傳送的目的地址不是累加器A,

;因此標志位沒有變化

2.外部RAM及I/O端口與累加器A之間的數(shù)據(jù)傳送

在MCS-51系統(tǒng)中,由于擴展I/O端口與外部RAM統(tǒng)一編碼,即擴展I/O端口地址占用外部RAM地址空間的某一單元,因此外部RAM及擴展I/O端口的讀寫操作指令、操作時序完全相同。只能通過累加器A存取外部RAM和擴展I/O端口,這類指令操作碼助記符為“MOVX”,其中“X”的含義是“eXternal”(外部),指令格式、機器碼如表示3-2所示。

表3-2外部RAM與累加器A之間的數(shù)據(jù)傳送指令說明:

(1)當通過DPTR寄存器間接尋址方式讀寫外部RAM及擴展I/O端口時,先將16位外部RAM地址或I/O端口地址放在數(shù)據(jù)指針DPTR寄存器中(DPTR寄存器就是為了訪問外部RAM而設置的),然后以DPTR作間接尋址寄存器,通過累加器A進行讀寫,這時外部RAM低8位地址A7~A0通過P0口輸出,高8位地址A15~A8通過P2口輸出。下面以讀寫外部RAM的3FFFH存儲單元為例,介紹外部RAM讀寫方法。

MOV DPTR,#3FFFH ;將要讀寫的外部RAM存儲單元地址3FFFH以立即數(shù)形式傳送到

;DPTR寄存器中

MOVXA,@DPTR ;將DPTR指定的外部存儲單元(3FFFH)內(nèi)容送累加器A(讀外部

;RAM)

MOVX@DPTR,A;

將累加器A輸出到DPTR指定的外部存儲單元(3FFFH)中(寫外部RAM)

(2)當通過R0或R1寄存器間接尋址方式讀寫外部RAM或擴展I/O端口時,先將外部RAM存儲單元或I/O端口低8位地址放在R0或R1寄存器中,然后以R0或R1作間接尋址寄存器,通過累加器A進行讀寫,這時外部RAM低8位地址A7~A0通過P0口輸出,尋址范圍是256個存儲單元。在讀寫期間P2口處于I/O方式,且P2口鎖存器不變。因此,使用Ri間接尋址方式訪問外部RAM具有更大的靈活性:在沒有外部程序存儲器的情況下,當外部RAM容量小于256字節(jié)時,通過Ri間接尋址讀寫外部RAM或擴展的I/O端口時,可將P2口作為一般I/O口使用,以增加I/O引腳數(shù)目;當外部RAM容量大于256字節(jié)時,以頁面方式讀寫外部RAM時,P2口中沒有使用的I/O引腳,可以作為輸出引腳使用。下面仍以讀寫外部RAM的3FFFH存儲單元為例,介紹通過Ri間接尋址讀寫外部RAM的方法。

MOVP2,#3FH ;

將要讀寫的外部RAM存儲單元高8位地址3FH以立即數(shù)方式傳

;送到P2口中(寫入P2口鎖存器)

MOVR1,#0FFH ;將要讀寫的外部RAM存儲單元低8位地址0FFH以立即數(shù)方式傳送到

;R1寄存器中

MOVXA,@R1;將R1指定的外部存儲單元低8位地址0FFH通過P0口輸出,由于P2

;口保持不變,結(jié)果外部RAM3FFFH單元被選中,并讀入累加器A中

MOVX@R1,A ;將R1指定的外部存儲單元低8位地址0FFH通過P0口輸出,由于P2

;口保持不變,外部RAM的3FFFH單元被選中,結(jié)果累加器A的內(nèi)容傳 ;送到3FFFH單元(寫入)

由于外部RAM與內(nèi)部RAM之間不能直接傳送,因此當需要將外部RAM傳送到內(nèi)部RAM時,可通過累加器A作中介。例如,通過如下指令將外部RAM3FFFH單元內(nèi)容傳送到內(nèi)部RAM2FH單元:

MOV DPTR,#3FFFH ;將外部RAM地址以立即數(shù)方式送數(shù)據(jù)指針DPTR

MOVX A,@DPTR ;將外部RAM3FFFH單元內(nèi)容讀到累加器A中

MOV 2FH,A ;將累加器A中的內(nèi)容送內(nèi)部RAM2FH單元中

外部RAM不同存儲單元之間也不能直接傳送,也需要通過累加器A作中介。

例3.2

把外部RAM的0100H單元內(nèi)容傳送到0120H單元中(兩單元之間的數(shù)據(jù)傳送)。

MOV DPTR,#0100H ;DPTR←單元地址0100H

MOVX A,@DPTR ;Acc←0100H單元內(nèi)容

MOV DPTR,#0120H ;DPTR←單元地址0120H

MOVX @DPTR,A ;0120H單元←Acc

例3.3

將外部RAM0080H~009FH單元,共32字節(jié)傳送到以00C0H為首地址的外部RAM中。對于標準MCS-51來說,在外部RAM之間進行批量數(shù)據(jù)傳送時,可先將外部RAM數(shù)據(jù)傳送到內(nèi)部RAM中,然后再傳送到外部RAM目標地址。

參考程序如下:

;先將外部RAM數(shù)據(jù)傳送到內(nèi)部RAM30H~4FH中

MOV R0,#30H

MOV R7,#32

MOV DPTR,#0080H

LOOP1:

MOVX A,@DPTR

MOV @R0,A

INC DPTR

INC R0

DJNZ R7,LOOP1

;再將暫存于內(nèi)部RAM30H~4FH中的數(shù)據(jù)傳送到外部RAM目標地址中

MOV R0,#30H

MOV R7,#32

MOV DPTR,#00C0H

LOOP2:

MOV A,@R0

MOVX @DPTR,A

INC DPTR

INC R0

DJNZ R7,LOOP2

利用增強型MCS-51雙DPTR指針,完成外部RAM不同區(qū)域之間的數(shù)據(jù)傳送要簡單得多,如實現(xiàn)上述數(shù)據(jù)傳送的程序可改為:

MOV R7,#32 ;定義傳送字節(jié)數(shù)

MOV DPTR,#0080H ;數(shù)據(jù)塊在外部RAM首地址傳送第一個DPTR指針

INC AUXR1 ;切換數(shù)據(jù)指針,指向目標地址

MOV DPTR,#00C0H ;外部RAM目標地址傳送另一DPTR指針

LOOP:

INC AUXR1 ;切換DPTR指針,指向源地址

MOVX A,@DPTR ;取外部RAM數(shù)據(jù)

INCDPTR

INC AUXR1 ;切換DPTR指針,指向目標地址

MOVX @DPTR,A ;數(shù)據(jù)送外部RAM目標地址

INCDPTR

DJNZR7,LOOP ;循環(huán),直到傳送完送32字節(jié)

可見利用雙DPTR指針后,程序段結(jié)構(gòu)簡潔,也無須使用內(nèi)部RAM作緩沖。

3.累加器A與程序存儲器ROM之間的數(shù)據(jù)傳送指令

為了取出存放在程序存儲器中的表格數(shù)據(jù),MCS-51提供了兩條查表指令,這兩條指令的操作碼助記符為“MOVC”,其中“C”的含義是“Code(代碼)”,表示操作對象是程序存儲器,指令格式、機器碼如表3-3所示。

表3-3查表指令其中“MOVCA,@A+DPTR”指令以DPTR作為基址,加上累加器A內(nèi)容后,所得的16位二進制數(shù)作為待讀出的程序存儲器單元地址,并將該單元的內(nèi)容送到累加器A中。這條指令主要用于查表,例如在程序存儲器中,依次存放0~F的七段共陰極數(shù)碼顯示器的字模碼3F、06、5B、4F、66、6D、7D、07、7F、6F、77、7C、39、5E、79、71,則當需要在P1口輸出某一數(shù)碼,如“3”時,可通過如下指令實現(xiàn):

MOV DPTR,#2000H ;假設字模存放在2000H開始的程序存儲器中,通過該指令將字模;首地址傳送到DPTR寄存器中

MOV A,#03H ;把待顯示的數(shù)碼傳送到累加器A中

MOVC A,@A+DPTR ;2000H

+

03H,即2003H單元的內(nèi)容(4F)讀到累加器A中

MOV P1,A ;將數(shù)碼“3”對應的字模碼“4F”輸出到P1口

ORG 2000H

DB3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH,77H,7CH,39H,5EH,79H,71H從程序存儲器中讀出某一字節(jié)時,也可以使用PC內(nèi)容作為基址,通過“MOVCA,@A+PC”取出,但使用這條指令讀取ROM中表格數(shù)據(jù)時,表格數(shù)據(jù)項必須位于該指令后,靈活性差,例如:

MOV A,#03H ;把待顯示的數(shù)碼傳送到累加器A中

INCA ;因MOVC后的短跳轉(zhuǎn)指令占兩個字節(jié),表頭與MOVC指令差2個

;字節(jié)

INCA

MOVC A,@A+PC ;PC+03H單元內(nèi)容(4F)讀到累加器A中

SJMPNEXT ;跳過數(shù)據(jù)表,否則CPU會將數(shù)據(jù)表當指令執(zhí)行

DB3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH,77H,7CH,39H,5EH,79H,71H

NEXT:

由于程序存儲器只能讀出,不能寫入,因此,也就沒有寫程序存儲器指令。

4.堆棧操作指令

堆棧操作也是計算機系統(tǒng)基本操作之一。設置堆棧操作的目的是為了迅速保護斷點和現(xiàn)場,以便在子程序或中斷服務子程序運行結(jié)束后,能正確返回主程序。MCS-51堆棧操作指令格式、機器碼如表3-4所示。

表3-4MCS-51堆棧操作指令有關MCS-51堆棧操作的過程,已在第2章中介紹過,這里只強調(diào)堆棧操作應注意的問題:

(1)由于MCS-51堆棧操作指令中的操作數(shù)只能使用直接尋址方式,不能使用寄存器尋址方式,如將累加器A壓入堆棧時,指令格式為:

PUSH Acc ;Acc是累加器A的寄存器名,本質(zhì)上屬于直接尋址

在堆棧操作指令中,累加器Acc不能簡寫為A。

(2)在子程序開始處安排若干條PUSH指令,把需要保護的特殊功能寄存器內(nèi)容壓入堆棧(即內(nèi)部RAM),在子程序返回指令前,安排相應的POP指令,將寄存器原來內(nèi)容彈出,但PUSH和POP指令必須成對,且入棧順序與出棧順序相反,因此子程序結(jié)構(gòu)如下:

PUSH PSW ;保護現(xiàn)場

PUSH ACC

;子程序?qū)嶓w

POP ACC

;恢復現(xiàn)場

POP PSW

RET ;子程序返回

5.字節(jié)交換指令

字節(jié)交換指令也屬于數(shù)據(jù)傳送指令范疇,不過交換后,源操作數(shù)與目的操作數(shù)內(nèi)容相互對調(diào),MCS-51提供了四條字節(jié)交換指令和兩條半字節(jié)交換指令,這些指令格式、機器碼如表3-5所示。

表3-5MCS-51交換指令由于字節(jié)交換指令第二操作數(shù)支持寄存器尋址、直接尋址和間接尋址,因此內(nèi)部RAM(00~0FFH)、特殊功能寄存器中任一單元均可以與累加器A進行交換。但半字節(jié)交換指令中的第二操作數(shù)僅支持寄存器間接尋址方式,因此僅有內(nèi)部RAM低4位能與累加器A低4位(b3~b0)直接交換。

例3.4

假設累加器A的內(nèi)容為12H,而R0的內(nèi)容為34H,則執(zhí)行:

XCHA,R0

指令后,累加器A的內(nèi)容為34H,R0的內(nèi)容為12H,即A和R0的內(nèi)容交換了,這與數(shù)據(jù)傳送指令不同,數(shù)據(jù)傳送指令執(zhí)行后,源操作數(shù)內(nèi)容覆蓋了目的操作數(shù)原來內(nèi)容。

例3.5

設累加器A為1EH,R0的內(nèi)容為2FH,內(nèi)部RAM2FH單元的內(nèi)容為37H,則執(zhí)行

XCHDA,@R0

指令后,累加器A的內(nèi)容為17H,內(nèi)部RAM2FH單元的內(nèi)容將為3EH,即A與寄存器R0指定的內(nèi)部RAM單元的低4位對調(diào),而高4位不變。3.1.2算術運算指令

MCS-51提供了豐富的算術運算指令,如加法運算、減法運算、增1指令、減1指令以及乘法、除法指令等。

一般情況下,算術運算指令執(zhí)行后會影響程序狀態(tài)字寄存器PWS中相應的標志位。

1.加法指令

加法指令操作碼助記符、指令格式以及機器碼如表3-6所示。

表3-6MCS-51加法指令由表3-6可見:

(1)所有加法指令的目的操作數(shù)均是累加器A,源操作數(shù)支持寄存器尋址、直接尋址、寄存器間接尋址、立即數(shù)尋址四種尋址方式。因此加數(shù),即源操作數(shù)可以是內(nèi)部RAM(00~FFH)、特殊功能寄存器或8位立即數(shù),結(jié)果存放在累加器A中。

(2)加法指令執(zhí)行后將影響進位標志Cy、溢出標志OV、輔助進位標志Ac以及奇偶標志P。相加后,若b7位有進位,則Cy為1;反之為0。b7有進位,表示兩個無符號數(shù)相加時,結(jié)果大于255,和的低8位存放在累加器A中。

計算機并不知道參加運算的兩個數(shù)是無符號數(shù)還是有符號數(shù),程序員只能借助溢出標志OV來判別帶符號數(shù)相加是否溢出。對于帶符號數(shù)來說,b7是符號位(0表示正數(shù),1表示負數(shù)),且負數(shù)用補碼表示。于是當兩個正數(shù)相加時,如果累加器A的b7為1,表示結(jié)果是負數(shù),不可能,即和大于

+127;同理,當兩個負數(shù)相加時,如果累加器A的b7為0,表示結(jié)果是正數(shù),同樣不可能,即和小于

-128。即在加法指令中,溢出標志OV置1的條件是:兩個操作數(shù)的符號相同(即b7位同為0或1),但結(jié)果的符號位相反。對于帶符號數(shù)加法運算來說,當溢出標志OV為1,結(jié)果不正確。

相加后,若b3位向b4位進位,則Ac為1;反之為0。

由于奇偶標志P總是體現(xiàn)累加器A中“1”的奇偶性,因此P也會改變。

(3)帶進位加法指令中的累加器A除了加源操作數(shù)外,還需要加上程序狀態(tài)字PSW寄存器中的進位標志Cy。設置帶進位加法指令的目的是為了實現(xiàn)多字節(jié)加法運算。例如,可通過如下指令將存放在30H、31H單元中的16位二進制數(shù)與存放在32H、33H單元中的16位二進制數(shù)相加(假設結(jié)果存放在30H、31H中):

MOV A,30H ;將被加數(shù)低8位送寄存器A中

ADD A,32H ;與加數(shù)低8位(32H單元內(nèi)容)相加,結(jié)果存放在A中

MOV 30H,A ;將和的低8位保存到30H單元中

MOV A,31H ;將被加數(shù)高8位送寄存器A中

ADDC A,33H ;與加數(shù)高8位(33H單元內(nèi)容)相加,結(jié)果存放在A中

;由于低8位相加時,結(jié)果可能大于0FFH,產(chǎn)生進位,因此高8位相加;時用ADDC指令

MOV 31H,A ;將和的高8位保存到31H單元中

2.減法指令

減法指令操作碼助記符、指令格式以及機器碼如表3-7所示。

表3-7MCS-51減法指令

MCS-51只有帶借位的減法指令,被減數(shù)是累加器A,減數(shù)可以是內(nèi)部RAM、特殊功能寄存器或立即數(shù)之一,結(jié)果存放在累加器A中。與加法指令類似,操作結(jié)果同樣會影響標志位:

Cy為1,表示被減數(shù)小于減數(shù),產(chǎn)生借位;

OV同樣用于判別兩個帶符號數(shù)相減后,差是否超出8位帶符號數(shù)所能表示的范圍(-128~+127)。當兩個異號數(shù)相減時,差的符號與被減數(shù)相反,則溢出標志OV為1,結(jié)果不正確。例如,被減數(shù)為正數(shù),減數(shù)為負數(shù),相減后,結(jié)果應該是正數(shù),但如果累加器A的b7為1,即負數(shù),則表明結(jié)果不正確。相減時,如果b3位向b4位借位,則Ac為1;反之為0。

奇偶標志P總是體現(xiàn)累加器A中“1”的奇偶性,因此P也會變化。

由于MCS-51指令系統(tǒng)只有帶借位的減法指令,因此,當需要執(zhí)行不帶借位的減法指令時,先執(zhí)行“CLRC”指令,將進位標志Cy清0。

例3.6

用減法指令求內(nèi)部RAM兩單元的差值(假設被減數(shù)存放在內(nèi)部RAM30H單元中,減數(shù)存放在31H單元中,差放在40H單元中)。

MOV A,30H ;被減數(shù)送寄存器A

CLR C ;進位標志Cy清0

SUBB A,31H ;減31H單元

MOV 40H,A ;結(jié)果保存到40H單元

3.加1指令

加1指令也稱為“增量指令”,操作結(jié)果是操作數(shù)加1。加1指令操作碼助記符、指令格式以及機器碼如表3-8所示。

表3-8MCS-51加1指令加1指令不影響標志位,只有操作對象為累加器A時,才影響奇偶標志位P。

當操作數(shù)初值為0FFH,則加1后,將變?yōu)?0H。

盡管加1指令與加數(shù)為1的加法指令同樣會使操作數(shù)增1,但彼此并不完全相同,

例如:

INCA ;通過增量指令使累加器A內(nèi)容加1

該指令除了影響奇偶標志位P外,不影響其他標志位。

ADDA,#01H ;通過加法指令使累加器A內(nèi)容加1

該指令同樣會使累加器A內(nèi)容加1,但該指令將影響Cy、OV、Ac以及P標志位,且指令機器碼占用兩個字節(jié)。

當操作數(shù)是某一I/O口,如“INCP1”時,先將P1口鎖存器內(nèi)容讀出,加1后,再寫入P1口鎖存器中,因此INCPi(i

=

0,1,2,3)屬于“讀—改—寫”指令。

4.減1指令

減1指令使操作數(shù)減1。減1指令操作碼助記符、指令格式以及機器碼如表3-9所示。

表3-9MCS-51減1指令與加1指令情況類似,減1指令也不影響標志位,只有當操作數(shù)是累加器A時,才影響奇偶標志位P。

當操作數(shù)的初值為00H時,減1后,結(jié)果將變?yōu)镕FH。

其他情況與加1指令類似。

5.乘法指令

MCS-51提供了8位無符號數(shù)乘法指令,該指令操作碼助記符、指令格式、機器碼如表3-10所示。

表3-10MCS-51乘法指令被乘數(shù)放在累加器A(8位無符號數(shù))中,乘數(shù)放在寄存器B(8位無符號數(shù))中,乘積(16位無符號數(shù))的高8位放在寄存器B中,低8位放在累加器A中。

該指令影響標志位:當結(jié)果大于255時,OV為1;反之為0。進位標志Cy總為0;AC保持不變;奇偶標志P隨累加器A中“1”的個數(shù)變化而變化。

MCS-51沒有提供8位

×

16位、16位

×

16位、16位

×

24位等多字節(jié)乘法指令,只能通過單字節(jié)乘法指令實現(xiàn)多字節(jié)乘法運算,可采用圖3-2所示算法實現(xiàn)相應的運算。

圖3-2多字節(jié)乘法算法

(a)

16位

×

8位;(b)

16位

×

16位;(c)

24位

×

16位在16位乘8位運算中,16位被乘數(shù)占2字節(jié),用BA表示;8位乘數(shù)占1字節(jié),用C表示,則乘積為24位。顯然“A*C”為16位,“B*C”為24位。因此,可用如圖3-2(a)所示算法實現(xiàn)。

在16位乘16位運算中,16位被乘數(shù)占2字節(jié),用BA表示;16位乘數(shù)也占2字節(jié),用DC表示,則乘積為32位。顯然“A*C”為16位,“B*C”為24位;“A*D”為24位,“B*D”為32位。因此,可用如圖3-2(b)所示算法實現(xiàn)。

而在24位乘16位運算中,24位被乘數(shù)占3字節(jié),用CBA表示;16位乘數(shù)占2字節(jié),用ED表示,乘積應該為40位。顯然“A*D”為16位,“B*D”為24位,“C*D”為32位;“A*E”為24位,“B*D”為32位,“E*C”為40位。因此,可用如圖3-2(c)所示算法實現(xiàn)。

例3.7

編寫一程序段,實現(xiàn)16位

×

8位運算。

;功能:16位乘8位運算程序段

;假設16位被乘數(shù)存放存在46H、47H單元中,8位乘數(shù)存放在49H單元中

;24位乘積保存在42H、43H、44H單元中

PROCMUL1608 ;16位

×

8位運算子程序

MUL1608:

;計算“A*C”

MOVA,47H;取被乘數(shù)低8位

MOVB,49H;取乘數(shù)

MULAB

MOV44H,A;存乘積的低8位

MOV43H,B;存乘積的高8位

;計算“B*C”,并與“A*C”相加

MOVA,46H;取被乘數(shù)高8位

MOVB,49H;取乘數(shù)

MULAB

ADDA,43H;乘積低8位

+

(b15~b8)

MOV43H,A;保存結(jié)果到b15~b8

CLRA

ADDCA,B;乘積高8位

+

Cy

MOV42H,A;保存結(jié)果到b23~b16

RET

END

以上程序段代碼長度也不長,執(zhí)行時間為22個機器周期,并不算長。

例3.8

編寫一程序段,實現(xiàn)16位

×

8位運算。

;功能:16位乘16位運算程序段

;假設16位被乘數(shù)存放存在46H、47H單元中,16位乘數(shù)存放在48H、49H單元中

;32位乘積保存在41H、42H、43H、44H單元中

;使用資源:累加器Acc、寄存器B、PSW

PROCMUL1616 ;16位

×

18位運算子程序

MUL1616:

;計算“A*C”

MOVA,47H ;取被乘數(shù)低8位

MOVB,49H ;取乘數(shù)

MULAB

MOV44H,A ;存乘積的低8位

MOV43H,B ;存乘積的高8位

;計算“B*C”,并與“A*C”相加

MOVA,46H ;取被乘數(shù)高8位

MOVB,49H ;取乘數(shù)

MULAB

ADDA,43H ;低8位

+

(b15~b8)

MOV43H,A ;保存結(jié)果到b15~b8

CLRA

ADDCA,B ;乘積高8位

+

Cy

MOV42H,A ;保存結(jié)果到b23~b16

;計算“A*D”,并相加

MOVA,47H ;取被乘數(shù)低8位

MOVB,48H ;取乘數(shù)高8位

MULAB

ADDA,43H ;低8位

+

(b15~b8)

MOV43H,A ;保存結(jié)果到b15~b8

MOVA,42H

ADDCA,B ;加乘積高8位

MOV42H,A ;保存結(jié)果到b23~b16

CLRA

ADDCA,#0 ;加進位標志Cy

MOV41H,A ;保存;計算“B*D”,并相加

MOVA,46H ;取被乘數(shù)高8位

MOVB,48H ;取乘數(shù)高8位

MULAB

ADDA,42H ;低8位

+

(b23~b16)

MOV42H,A ;保存到b23~b16

MOVA,41H

ADDCA,B ;加乘積高8位

MOV41H,A ;保存結(jié)果到b31~b24

RET

END

例3.9

編寫一程序段,實現(xiàn)24位

×

16位運算。

;假設24位被乘數(shù)存放存在45H、46H、47H單元中,乘數(shù)存放在48H、49H單元中

;40位乘積保存在40H、41H、42H、43H、44H單元中

PROCMUL2416 ;24位

×

16位運算子程序

MUL2416:

;低8位乘被乘數(shù)低8位

MOVA,49H ;取乘數(shù)低8位

MOVB,47H ;取被乘數(shù)低8位

MULAB

MOV44H,A ;存乘積低8位(b7~b0)

MOV43H,B ;存乘積高8位(b15~b8)

;低8位乘被乘數(shù)次高8位

MOVA,49H ;取乘數(shù)低8位

MOVB,46H ;取被乘數(shù)次高8位

MULAB

ADDA,43H ;乘積低8位

+

(b15~b8)

MOV43H,A ;保存b15~b8

CLRA

ADDCA,B ;乘積高8位加

+

Cy,乘積最高位最大為FEH,即使加1,

;也不可能溢出

MOV42H,A ;保存b23~b16

;低8位乘被乘數(shù)最高8位

MOVA,49H ;取乘數(shù)低8位

MOVB,45H ;取被乘數(shù)最高8位

MULAB

ADDA,42H ;加b23~b16

MOV42H,A ;保存結(jié)果b23~b16

CLRA

ADDCA,B ;乘積高8位加

+

Cy,乘積最高位最大為FEH,即使加1,

;也不可能溢出

MOV41H,A ;保存b31~b24

;高8位乘被乘數(shù)低8位

MOVA,48H ;取乘數(shù)高8位

MOVB,47H ;取被乘數(shù)低8位

MULAB

ADDA,43H ;乘積低8位

+

(b15~b8)

MOV43H,A ;保存b15~b8

MOVA,42H ;取b23~b16

ADDCA,B ;乘積高8位

+

(b23~b16)

+

Cy

MOV42H,A ;保存b23~b16

CLRA

ADDCA,41H ;(b31~b24)

+

Cy

MOV41H,A ;保存b31~b24

CLRA

ADDCA,#0 ;加進位標志Cy

MOV40H,A ;保存b39~b32

;高8位乘被乘數(shù)次高8位

MOVA,48H ;取乘數(shù)高8位

MOVB,46H ;取被乘數(shù)次高8位

MULAB

ADDA,42H ;乘積低8位

+

(b23~b16)

MOV42H,A ;保存b23~b16

MOVA,41H ;取b31~b24

ADDCA,B ;乘積高8位

+

(b31~b24)

+

Cy

MOV41H,A ;保存b31~b24

CLRA

ADDCA,40H ;b39~b32

+

進位標志Cy

MOV40H,A ;保存b39~b32

;高8位乘被乘數(shù)最高8位

MOVA,48H ;取乘數(shù)高8位

MOVB,45H ;取被乘數(shù)最高8位

MULAB

ADDA,41H ;乘積低8位

+

(b31~b24)

MOV41H,A ;保存b31~b24

MOVA,40H ;取b39~b32

ADDCA,B ;加乘積高8位

+

(b39~b32)

+

Cy

MOV40H,A ;保存b39~b32

RET

END

6.除法指令

MCS-51提供了8位無符號數(shù)除法指令,該指令操作碼助記符、指令格式、機器碼如表3-11所示。

表3-11MCS-51除法指令被除數(shù)放在累加器A(8位無符號數(shù))中,除數(shù)放在寄存器B(8位無符號數(shù))中,商(8位無符號數(shù))放在累加器A中,余數(shù)(8位無符號數(shù))放在寄存器B中。顯然余數(shù)取值范圍為0~(除數(shù)

-1)。

該指令影響標志位:如果除數(shù)(即寄存器B)不為0,執(zhí)行執(zhí)行后,溢出標志OV總為0;如果除數(shù)為0,執(zhí)行后,結(jié)果將不確定,OV置1。

AC保持不變;進位標志Cy總為0;奇偶標志P位隨累加器A中“1”的個數(shù)變化而變化。盡管MCS-51沒有提供16位

÷

8位、32位

÷

16位等多位除法運算指令,但可以借助減法或類似多項式除法運算規(guī)則完成多位除法運算,參考例3.27。

MCS-51沒有多字節(jié)乘、除法指令,在電機調(diào)速、開關電源控制等應用系統(tǒng)中,有時顯得不方便,盡管可通過軟件方式實現(xiàn)多字節(jié)乘法、除法運算,但耗時長,系統(tǒng)反應速度慢。為此,InfineonXC886系列提供了32位硬件乘法、除法部件MDU。

7.十進制加法校正指令

在介紹十進制加法調(diào)正指令前,先來看BCD碼加法運算存在的問題。

例3.10BCD碼25存放在累加器A中,即A

=

00100101B;另一BCD碼36存放在寄存器R2中,即R2

=

00110110B。當通過“ADDA,R2”指令相加時,CPU視為兩個二進制數(shù)相加,運算結(jié)果如下:

A=00100101

+R2=00110110

A←01011011(結(jié)果是5BH,即十進制的91)而我們知道25

+

36

=

61,之所以得不到正確結(jié)果是因為在BCD中,用二進制表示十進制數(shù)時,僅使用0~9,即二進制0000~1001十個數(shù)碼。因此,相加后,當?shù)?位大于1001時,應該加06H,使低4位(即BCD碼個位)向b4進位,獲得正確結(jié)果,例如:

A=

01

011011

+

6校正

00000110

A←01100001(結(jié)果是61)顯然,高4位也存在類似情況,即根據(jù)運算結(jié)果加60H校正。下面再來看另一種情況下,即低4位向高4位進位時,也需要校正。

例3.11

假設BCD碼19存放在累加器A中,即A

=

00011001B;另一BCD碼38存放在寄存器R2中,即R2=00111000B。當通過“ADDA,R2”指令相加時,運算結(jié)果如下:

A=

00011001

+

R2=00111000

A←01010001(結(jié)果是51H,即十進制的81)而19

+

38

=

57,之所以得不到正確結(jié)果是因為8

+

9

=

17,在二進制加法中為11H,同樣需要加6校正。因此,當b3位向b4位進位,即輔助進位標志Ac有效時,要加6校正。事實上,設置輔助進位標志Ac的目的主要是為了判別BCD加法運算是否需要校正。同樣,高位也存在類似問題,當b7有進位,即Cy為1時,也需要加60H進行校正。可見用ADD指令完成BCD碼加法運算時,高4位或低4位大于1001,以及Ac或Cy有效時,必須加06H、60H或66H進行校正,才能獲得正確的結(jié)果。十進制加法校正指令就是為此而設置,該指令操作碼助記符、指令格式、機器碼如表3-12所示。

表3-12MCS-51

BCD加法校正指令該指令用于BCD加法校正,需放在ADD指令后,例如:

ADD A,R2 ;兩個BCD碼相加

DA A ;將累加器A中的結(jié)果校正后轉(zhuǎn)化為BCD

值得注意的是十進制校正指令只能放在加法指令后,不能單獨使用“DAA”指令將累加器A中的內(nèi)容轉(zhuǎn)化為BCD碼。

MCS-51沒有提供BCD碼減法校正指令,但可以通過“補碼”概念,將BCD碼減法運算變成BCD碼加法運算。我們知道兩位BCD可以表示00~99,需要用8位二進制存放;三位BCD可以表示000~999,需要用12位二進制存放;四位BCD可以表示0000~9999之間的數(shù),需要用16位二進制存放,因此,XY

-

xy

=

XY

+

100

-

xy(100的BCD需要用12位二進制存放,其中的1自然丟失)。

當XY≥xy時,“XY

+

100

-

xy”就是XY

-

xy;當XY<xy時,“XY

+

100

-

xy”是“XY

-

xy”的補碼。

由于其中的“100”為BCD碼,可表示為“99H+1H”,即“9AH”。因此可直接用減法指令求出“100

-

xy”=“9AH

-

xy”的BCD碼。

例3.12

假設兩位BCD碼形式的被減數(shù)、減數(shù)分別存放在VAR1和VAR2單元中,試編寫一程序段求“VAR1

-

VAR2”,結(jié)果存放在VAR3單元中。

參考程序如下:

CLR C ;清進位標志Cy

MOV A,#9AH ;把BCD碼“100”等效表示碼送累加器A

SUBB A,VAR2 ;計算“100

-

VAR2”,結(jié)果為BCD形式

ADD A,VAR1 ;加被減數(shù)

DA A ;校正

MOV VAR3,A ;保存“VAR1

-

VAR2”結(jié)果

例3.13

將R2中以壓縮形式存放的兩位BCD碼減1。

與上例有所不同,減1相當于加99(因為99H

+

1

-

1就是99H)。這樣實現(xiàn)兩位BCD碼減1的程序如下:

MOV A,R2

ADD A,#99H

DA A

MOV R2,A

對于3位BCD碼來說,XYZ

-

xyz

=

ZYX

+

1000

-

xyz。

當XYZ≥xyz時,“XYZ

+

1000

-

xyz”就是XYZ

-

xyz;當XYZ<xyz時,“XYZ

+

1000

-

xyz”是“XYZ

-

xyz”的補碼。同理,為了能用減法指令求出“1000

-

xyz”的BCD碼,可用“99AH”表示“1000

-

xyz”算式中十進制數(shù)“1000”(因為“99AH”加“6”校正后正好是“1000H”)。

例3.14

三位壓縮形式BCD碼被減數(shù)存放在81H、80H單元中,減數(shù)存放在31H、30H單元中,試編寫一程序段求出兩者的差,結(jié)果存放在81H、80H單元中。

CLR C

MOV A,#9AH

SUBB A,30H ;低8位相減

MOV R2,A ;暫時保存低8位中間結(jié)果

MOV A,#09H

SUBB A,31H ;高4位相減

ANL A,#0FH ;屏蔽高位

MOV R3,A ;暫時保存高8位中間結(jié)果

MOV R0,#80H

MOV A,@R0 ;取被減數(shù)低8位

ADD A,R2 ;低8位相加

DA A ;校正

MOV @R0,A ;保存和的十位、個位

INCR0 ;R0加1

MOV A,@R0 ;取被減數(shù)百位

ADDC A,R3 ;百位相加

DA A ;校正

ANL A,#0FH ;屏蔽高4位

MOV @R0,A ;保存百位

例3.15

將R3/R2中以壓縮形式存放的三位BCD碼減1。

三位BCD減1,相當于加999(其實99AH減1就是999H)。因此,實現(xiàn)三位BCD碼減1的程序如下:

MOV A,R2 ;取十位、個位

ADD A,#99H

DA A

MOV R2,A ;保存加99后的十位、個位結(jié)果

MOV A,R3 ;取百位

ADDC A,#09H

DA A ;百位加9并校正

ANL A,#0FH ;屏蔽高4位

MOV R3,A ;保存百位3.1.3邏輯運算指令

邏輯運算在計算機指令系統(tǒng)中的重要性并不亞于算術運算指令。MCS-51提供了豐富的邏輯運算指令,包括邏輯非(取反)、與、或、異或以及循環(huán)移位操作等。

邏輯運算指令格式、操作碼助記符、機器碼等如表3-13所示。

表3-13MCS-51邏輯運算指令這類指令的特點是不影響程序狀態(tài)字寄存器PSW中的標志位(但以Acc為目的操作數(shù)時將影響P標志)。只有帶進位Cy循環(huán)移位時,才影響Cy和奇偶標志P。

邏輯運算均按位進行。例如當A

=

10100101B時,執(zhí)行“ANLA,#01011010B”指令后,累加器A為0。

常用邏輯與(ANL)指令將操作數(shù)中指定位清0。如可通過如下指令將P1口鎖存器的b4、b2位清0,而其他位不變。

ANLP1,#11101011B

在構(gòu)造立即數(shù)時,希望清0位取0,其他位取1。該指令執(zhí)行后,P1口鎖存器各位為

×××0×0××,可見指定位為0,其他位保持不變。

常用邏輯或(ORL)指令將操作數(shù)中指定位置1。如可通過如下指令將P1口鎖存器的b4、b2位置1,而其他位不變。

ORLP1,#00010100B

在構(gòu)造立即數(shù)時,希望置1位取1,其他位取0。該指令執(zhí)行后,P1口鎖存器各位為

×××1×1××,可見指定位為1,其他位保持不變。

常用邏輯異或(XRL)指令將操作數(shù)中指定位取反。如可通過如下指令將P1口鎖存器的b4、b2位取反,而其他位不變。

XRLP1,#00010100B

在構(gòu)造立即數(shù)時,希望取反位為1,其他位為0。

左循環(huán)移位“RLA”也常用于實現(xiàn)

×

2n(如2、4、8等)的運算。例如,當需要對累加器A進行乘4操作時,如果A小于3FH,用如下兩條左循環(huán)移位指令完成比用乘法指令速度快、代碼短。

RLA ;左循環(huán)移位一次,相當于乘2

RLA ;再左循環(huán)移位一次,相當于乘4

以上兩條指令執(zhí)行時間僅需2

×

1個機器周期,代碼長度為2

×

1字節(jié),但如使用乘法指令實現(xiàn)則需要6個機器周期(2

+

4),代碼長度為4字節(jié)(3

+

1)。

MOVB,#04H ;3字節(jié),執(zhí)行時間為2個機器周期

MULAB ;1字節(jié),執(zhí)行時間為4個機器周期3.1.4位操作指令

由于單片機在控制系統(tǒng)中主要用于控制線路通、斷,繼電器的吸合與釋放等,因此位操作指令在單片機指令系統(tǒng)占有重要地位。多數(shù)8位機依然保留了一位機功能,即提供了完整的位尋址功能和位操作指令。

MCS-51單片機具有豐富的位操作指令,在位運算指令中,進位標志Cy的作用類似于字節(jié)運算指令中的累加器A,因此Cy在位操作指令中,被稱為“位累加器”。在MCS-51中,位存儲器包括了內(nèi)部RAM20H~2FH單元的位存儲區(qū)以及特殊功能寄存器中支持位尋址的所有位。

MCS-51位操作指令操作碼助記符、指令格式、機器碼等如表3-14所示。

在位操作中,位存儲器均使用直接地址,在匯編語言指令中,有關特殊功能寄存器中位地址的表示方法第2章已介紹過。

在位操作中,除了使用位累加器Cy的位操作指令外,均不影響其他標志位。

MCS-51沒有提供位異或運算指令,當需要位異或運算時,可通過如下方式之一實現(xiàn):

(1)利用MCS-51的偶校驗標志P實現(xiàn)。根據(jù)偶校驗特征,PSW標志寄存器內(nèi)的偶校驗位為

P

=

ACC.7ACC.6ACC.5ACC.4ACC.3ACC.2ACC.1ACC.0

例如,設X、Y、Z均為位變量,則可通過如下指令求X、Y位變量的異或結(jié)果。

CLRA

MOVC,X ;位變量X送Cy

MOVAcc.0,C ;Acc.0←Cy

MOVC,Y ;位變量Y送Cy

MOVAcc.1,C ;Acc.1←Cy

MOVC,P ;把運算結(jié)果送Cy

MOVZ,C ;Cy送Z

當邏輯變量多于兩個時,使用這種方式將非常方便。例如,四個邏輯變量分別從P1.3、P1.2、P1.1、P1.0引腳輸入,可通過如下指令求其異或運算的結(jié)果:

MOVA,P1

ANLA,#0FH ;異或結(jié)果已經(jīng)在P標志中

3.1.5控制及轉(zhuǎn)移指令

以上介紹的指令均屬于順序執(zhí)行指令,即執(zhí)行了當前指令后,接著就執(zhí)行下一條指令。但在計算機中,只有順序執(zhí)行指令是不夠的,更一般的情況是:執(zhí)行了當前指令后,往往需要根據(jù)執(zhí)行結(jié)果做出判別,是繼續(xù)執(zhí)行隨后的指令,還是轉(zhuǎn)去執(zhí)行其他的指令系列,這就需要控制和轉(zhuǎn)移指令。

控制轉(zhuǎn)移指令包括跳轉(zhuǎn)(包括無條件跳轉(zhuǎn)和條件跳轉(zhuǎn))指令、調(diào)用指令、返回指令以及停機指令等。

1.無條件跳轉(zhuǎn)指令

MCS-51無條件跳轉(zhuǎn)指令操作碼助記符、格式、機器碼如表3-15所示。

表3-15無條件跳轉(zhuǎn)指令無條件跳轉(zhuǎn)指令的含義是執(zhí)行了該指令后,程序?qū)o條件跳到指令中給定的存儲器地址單元執(zhí)行,其中:

(1)長跳轉(zhuǎn)指令給出了16位地址,該地址就是轉(zhuǎn)移后要執(zhí)行的指令碼所在的存儲單元地址。因此,該指令執(zhí)行后,將指令中給定的16位地址裝入程序計數(shù)器PC。長跳轉(zhuǎn)指令可使程序跳到64

KB范圍內(nèi)的任一單元執(zhí)行,常用于跳到主程序、中斷服務程序入口處,如:

ORG0000H

LJMPMain ;其中Main是主程序入口地址標號

ORG0003H

LJMPINT0 ;INT0是外中斷0服務程序入口地址標號

(2)絕對跳轉(zhuǎn)指令AJMP只需11位地址,即該指令執(zhí)行后,僅將指令中給定的11位地址裝入程序計數(shù)器PC的低11位,而高5位(即PC15~PC11)保持不變,因此AJMP指令只能實現(xiàn)2KB(由于高5位地址編碼相同,而A10~A0的尋址范圍就是2KB)范圍內(nèi)的跳轉(zhuǎn),即轉(zhuǎn)入的存儲單元地址的高5位地址編碼與PC計數(shù)器當前值的高5位必須相同,否則就會出現(xiàn)跨頁錯誤。假設“AJMP267BH”指令存放在2000H單元,由于該指令占用兩個字節(jié),執(zhí)行后,PC=2002H,即0010000000000010B,由于低11位地址由AJMP指令給出,可見跳轉(zhuǎn)目標地址范圍在0010000000000000B~0010011111111111B,即2000H~27FFH之間,包含了“267B”,因而能夠跳轉(zhuǎn)。

(3)短跳轉(zhuǎn)指令“SJMPrel”中的rel是一個帶符號的8位地址,范圍在

-128~+127之間,當偏移量為負數(shù)(用補碼表示)時,向前跳轉(zhuǎn);而當偏移量為正數(shù)時,向后跳轉(zhuǎn)。

由于SJMP指令占兩個字節(jié),執(zhí)行該指令后,PC

=

××××

+

2(××××是SJMP指令碼的首地址)。當rel為FEH,即

-2時,跳轉(zhuǎn)地址等于PC

=

××××

+

2

-

2

=

××××,即又跳回SJMP指令碼首地址單元,將不斷重復執(zhí)行SJMP指令,相當于動態(tài)停機。在匯編語言中,常寫成:

Here:SJMPHere

或SJMP$

在匯編語言源程序中,$

表示指令的首地址。執(zhí)行這條指令,會使機器進入死循環(huán)。如果中斷處于允許狀態(tài),則當中斷有效時,將進入中斷服務程序,但從中斷服務程序返回后又重復執(zhí)行SJMP指令。

(4)在間接跳轉(zhuǎn)“JMP@A+DPTR”指令中,將DPTR內(nèi)容與累加器A相加,得到的16位地址作為PC的值。因此,通過該指令可以動態(tài)修改PC的值,跳轉(zhuǎn)地址由累加器A控制,常用于多分支跳轉(zhuǎn)指令。

2.調(diào)用指令

MCS-51調(diào)用指令操作碼助記符、指令格式、機器碼如表3-16所示。

表3-16調(diào)用指令可見調(diào)用指令與跳轉(zhuǎn)指令不同:調(diào)用指令用于執(zhí)行子程序,調(diào)用指令中的地址就是子程序的入口地址,子程序執(zhí)行結(jié)束后,要返回主程序繼續(xù)執(zhí)行。因此,調(diào)用時,需要將指令指針PC壓入堆棧,保存PC的當前值,以便在子程序執(zhí)行結(jié)束后,通過RET指令正確返回,例如:

LCALLSUB1 ;調(diào)用子程序SUB1

MOV2FH,A

SUB1:

PUSHPSW

POPPSW

RET

假設LCALLSUB1指令機器碼從1003H單元開始存放,由于該指令占3個字節(jié),則該指令后的“MOV2FH,A”指令機器碼將從1006H單元開始存放。執(zhí)行了“LCALLSUB1”指令后,PC也是1006H,正好是該指令下一條指令機器碼的首地址,為了能夠返回,先將1006H(即06H、10H)壓入堆棧,然后再將SUB1標號對應的存儲單元地址,即子程序入口地址裝入PC,執(zhí)行子程序中的指令系列,當遇到RET指令后,又自動將堆棧中的1006H,即斷點地址傳送

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論