第 3 章 MCS-51 單片機指令系統
1.MCS-51 單片機指令概述
- MCS-51系列單片機指令系統共有111條指令。
按功能分為5類:①數據傳送(29條)②算術運算(24條)③邏輯運算(24條)④控制轉移(17條)⑤布爾處理(17條)
按字節長度分為3類:①單字節指令(49條)②雙字節指令(46條)③三字節指令(只有16條)
按執行時間分為3類:①單機器周期指令(64條)②雙機器周期指令(45條)③四機器周期指令(只有2條)
- MCS-51單片機指令系統的特點:
- ① 助記符少:MCS-51指令系統用44種助記符表示了33種指令功能。
- ②空間和時間效率均較高:平均指令長度和平均指令執行時間短。
- ③更適合於實時控制: MCS-51指令系統中有17條布爾處理指令。
1.MCS-51單片機匯編語言指令格式

- 操作碼用來規定指令進行什么操作;
- 操作數則是指令操作的對象;
- 有單字節指令、雙字節指令、三字節不同長度的指令,格式不同:
- 1)單字節指令:指令只有一個字節,操作碼和操作數同在一個字節中。
- 2)雙字節指令:一個字節為操作碼,另一個字節是操作數。
- 3)三字節指令:操作碼占一個字節,操作數占二 個字節。其中操作數既可能是數據,也可能是地址。
操作數的特點:
① 操作數可以是數據本身,也可以是數據的地址、數據地址的地址或操作數的其他信息;
② 操作數可分為目的操作數和源操作數;
③ 操作數可用二進制數、十進制數或十六進制數表示;
④ 操作數的個數可以是0~3個;
⑤ 操作數與操作碼之間用空格分隔,操作數與操作數之間用逗號“,”分隔。
2.布爾處理機
- 布爾處理機——位處理機,專門用於位處理。
布爾處理機硬件主要由以下五部分支持:
① 布爾運算器ALU。
② 布爾累加器Cy(PSW.7)。
③ 布爾RAM區。
④ 布爾I/O口
⑤ 布爾指令集
3.指令中的常用符號
- 1)#:立即數前導符。#data:8 位立即數;#data16:16 位立即數。
- 2)direct:8 位直接地址,代表片內 RAM 或 SFR 的地址 00H~7FH 或 80H~FFH。
- 3)@:間接尋址符。在間接尋址方式中,表示間接尋址寄存器指針的前綴標志。如@Ri, @DPTR,@A+PC,@A+DPTR。
- 4)addr11:11 位目的地址。主要用於 ACALL 和 AJMP 指令中。
- 5)addr16:16 位目的地址。主要用於 LCALL 和 LJMP 指令中。
- 6)rel:帶符號的 8 位偏移地址。主要用於相對轉移指令,以形成轉移的目的地址,其 范圍是相對於下一條指令第 1 字節地址的−128~+127 個字節。
- 7)bit:位地址。代表片內 RAM 中的可尋址位 00H~7FH 及 SFR 中的可尋址位。
- 8)Rn(n=0~7):表示當前工作寄存器 R0~R7 中的任一個寄存器。
- 9)Ri(i=0 或 1):表示通用寄存器組中用於間接尋址的兩個寄存器 R0 或 R1。
- 10)A(或 ACC)、B:表示累加器、B 寄存器(A 是寄存器尋址方式,ACC 是直接尋 址方式的累加器)。
- 11)C:表示 PSW 中的進位標志位 Cy,也稱位累加器。
- 12)$:表示當前指令的地址。
- 13)/:在位邏輯與、邏輯或操作指令中,表示對該位先求反后再參與相應的邏輯運算, 但該位的內容保持不變。
- 14)(X):表示由 X 所指定的某寄存器或某單元中的內容。
- 15)((X)):表示由 X 間接尋址單元中的內容。
- 16)←:表示指令的操作結果是將箭頭右邊的內容傳送到左邊。
- 17)→:表示指令的操作結果是將箭頭左邊的內容傳送到右邊。
- 18) ∧ 、∨ 、⊕ :表示邏輯與、或、異或。
2.MCS-51 單片機的尋址方式
尋址方式——計算機指令中說明操作數所在地址的方法。
MCS-51 單片機的指令系統有 7 種尋址方式,分別為立即尋址、直接尋址、寄存器尋址、 寄存器間接尋址、基址加變址尋址、相對尋址和位尋址。
1.立即尋址
- 尋址空間:程序存儲器。
- 立即尋址是指
指令中直接給出操作數本身的尋址方式。指令中的操作數稱為立即數,立即數前面加“#”以區別直接尋址。

例如:MOV A,#45H
- 其中,45H就是立即數,指令的功能是把立即數45H傳送到累加器A中。參考下圖:

注:E0H為累加器A的字節地址。
- 在MSC-51型單片機中,除了有8位立即數外,還有一條16位立即數的數據傳送指令,即
MOV DPTR,#dataH,其功能是把16位立即數傳送到數據指針DPTR中。
例如:MOV DPTR,#1234H
- 上式表示把立即數1234H傳送到數據指針DPTR中,其中12H傳送到DPH,34H傳送到DPL中。參考下圖:

注:DPH的字節地址是83H,DPL的字節地址是82H。
2.直接尋址
- 尋址空間:內部RAM的低128字節和特殊功能寄存器SFR(直接尋址是訪問SFR的唯一尋址方式)。
- 指令中給出的不是操作數本身,而是操作數的單元地址稱為直接尋址。
- 直接尋址的指令有三種形式:

例如:MOV A, 45H
- 45H就是要操作的數據所在的單元地址,如果內RAM(45H)=36H,那么指令執行后(A)=36H。參考下圖:

例如:ANL 30H,#30H
- ANL是邏輯“與”操作指令,第一個30H是操作數地址,第二個30H是參加“與”運算的操作數。最后將“與”的結果存入第一個30H單元中。

例如:
MOV 40H,B // 將寄存器B中的數值送入內部RAM的40H單元中
INC 30H // 將內部RAM的30H單元中的數值加一
MOV TL0,R7 // 將寄存器R7中的數值送入特殊功能寄存器TL0中
3.寄存器尋址
-
尋址空間:R0~R7,A、B、Cy(位),DPTR。
-
寄存器尋址方式:指令給出存放操作數據的某個寄存器,而不是數據本身。即指出寄存器組R0~R7中的某一個或其他寄存器(A,B,DPTR和進位Cy等)的內容為操作數。當寄存器為Rn時,操作碼的低3位指明是R0~R7中的哪一個。
-
寄存器尋址有三種指令形式:

例如:MOV A,R7
- 指令中R7就是存放源操作數據的寄存器,如果(R7)=19H,則指令執行后(A)=19H,而上述指令為:01011111,其中低三位111就表示操作數寄存器是R7。

例如:
MOV R1,B // 將寄存器B中的數值送入寄存器R1中
INC R2 // 將寄存器R2中的數值加一
MOV A,R5 // 將寄存器R5中的數值送入累加器A中
4.寄存器間接尋址
-
尋址空間:內部RAM(@R0,@R1,SP)和外部數據存儲器(@R0,@R1,@DPTR)。
-
將要處理的數據的地址放在寄存器中,即用寄存器中的數據作為存儲單元的地址數值。
-
寄存器間接尋址的操作數要以寄存器的符號形式表示,即在寄存器前面添加前綴“@”。
-
寄存器間接尋址有三種指令形式:

例如:已知(R0)=30H,(30)=40H,分析指令:MOV A,@R0
- 這是累加傳送指令,設(R0)=30H,則該指令是把內部RAM的30H寫入累加器A中。

例如:
MOV @R1,#05H // 將數值05H送入以R1內數值為地址的內部RAM中
ADD A,@R1 // 將A寄存器中的數值加上R1內部數值為地址的內部RAM單元中的數據,結果存放於A中
MOVX A,@DPTR // 將以DPTR中數值為地址的外部數據存儲器的內容送至A中存儲
5.基址加變址尋址
- 基址加變址尋址:
將要處理的數據地址分開存放在基地址和變地址寄存器中,即用一個寄存器(稱為基址寄存器)中的數據作為存儲單元的基本地址數值,用另一個寄存器(稱為變址寄存器)中的數據作為存儲單元的偏移地址數值,實際尋址單元的地址數值為兩個寄存器內容之和。 - 尋址空間:程序存儲器(@A+DPTR,@A+PC)
- 以DPTR或PC作基址寄存器,A作變址寄存器(存放8位無符號數),兩者相加形成16位程序存儲器地址作操作數地址,用改地址去訪問ROM。
- 該尋址方式是單字節指令,用於讀出程序存儲器中數據表格中的常數(查表)到累加器A中。
例如:已知(DPTR)=1234H,(A)=50H,程序存儲器(1284H)=65H,分析如下執行結果:MOVC A,@A+DPTR。
- DPTR與A相加后的地址是1284H,而實際尋址地址是1284H,其操作數是65H,最后將65H送至累加器A中。

例如:
MOVC A,@A+PC // 將A和PC兩個寄存器的數值相加之和作為程序存儲器中的數據地址,將該地址的內容送到A中
MOVC A,@A+DPTR // 將A和DPTR兩個寄存器的數值相加之和作為程序存儲器中的數據地址,將該地址的內容送到A中
6.相對尋址
- 相對尋址是把程序計數器PC的內容加上指令格式中的形式地址D而形成操作數的有效地址。程序計數器的內容就是當前指令的地址。“相對”尋址,就是相對於當前的指令地址而言。
- 尋址空間:程序存儲器
- 在相對轉移指令中使用,相對轉移指令執行時,將當前的PC值加上指令中規定的偏移量rel,其和作為實際的轉移目標地址。
- PC的當前值是相對轉移指令下面一條指令的地址。
- 目標地址、當前的PC值和rel三者之間的關系:
- rel=目標地址-(PC)
- rel為補碼形式的8位地址偏移量(-128~+127)
- 相對轉移指令有三種指令形式:

例如:2000H:SJMP 06H
- 該指令是一條2B指令,它存儲在ROM 2000H、2001H這兩個單元中。當執行到該指令時,首先取出該指令,由於PC具有自動加1功能,取出指令后PC內容已加2,此時PC當前值為2002H,地址偏移量06H為正值,可得轉移的目的地址是2002H+06H=2008H,即程序將從2008處開始執行。執行過程如圖所示:

- 偏移量rel的計算公式
- 正向跳轉時: r e l = 目 的 地 址 − 轉 移 指 令 所 在 的 起 始 地 址 − 轉 移 指 令 的 字 節 數 = 地 址 差 值 − 轉 移 指 令 的 字 節 數 rel=目的地址-轉移指令所在的起始地址-轉移指令的字節數=地址差值-轉移指令的字節數 rel=目的地址−轉移指令所在的起始地址−轉移指令的字節數=地址差值−轉移指令的字節數
- 反向跳轉時,目的地址小於轉移指令的起始地址,rel用負數的補碼形式表示。 r e l = ( 目 的 地 址 − ( 轉 移 指 令 的 起 始 地 址 + 轉 移 指 令 的 字 節 數 ) ) 補 rel=(目的地址-(轉移指令的起始地址+轉移指令的字節數))_補 rel=(目的地址−(轉移指令的起始地址+轉移指令的字節數))補
有如下程序段
……
JNZ NEXT
……
NEXT:……
假設指令JNZ NEXT的地址為2000H(當前PC的值為2002H),標號NEXT的地址為2340H,則指令JNZ NEXT中的相對偏移量: rel=2340H-2002H=33EH
2340H:0010 0011 0100 0000
2002H:0010 0000 0000 0010
0010 0011 0100 0000
+ 0010 0000 0000 0010
--------------------------
0000 0011 0011 1110
--------------------------
0 3 3 E H
所以,rel=33EH
機器匯編時,該rel的值是在匯編時由匯編器計算,人工匯編時由程序員計算
指令JNZ NEXT執行時,將計算當前PC的值與rel之和(2002H+33EH=2340H),然后轉移到地址為2340H處執行
7.位尋址
- 尋址空間:片內RAM的20H~2FH中的128個可尋址位和11個字節地址能被8整除的SFR中的83個可尋址位,共210個位。
- 對內部RAM、特殊功能寄存器SFR中的位地址空間進行訪問尋址方式稱之為位尋址 。
- 注意:訪問累加器CY的尋址方式既可屬於寄存器尋址又可屬於位尋址。
- 位地址的表示有4種方法:
- ① 直接使用位尋址區中的位地址。
MOV C,7EH; (Cy)←(7EH) - ② 采用“字節地址.位號”表示方法。上述位地址7EH可以表示為2FH.6,相應指令為:
MOV C,2FH.6 ;(Cy)←(2FH.6) - ③ 采用“特殊功能寄存器名.位號”表示方法。
MOV C,ACC.0 ;(Cy)←(ACC.0) - ④ 使用位名稱。
SETB EA
- ① 直接使用位尋址區中的位地址。
注:SETB EA:EA置為1;CLR EA:EA置為0。
各尋址方式與相應的尋址空間
| 尋址方式 | 利用的變量 | 使用的空間 |
|---|---|---|
| 寄存器尋址 | R0~R7,A,B,CY,DPTR | 片內 |
| 直接尋址 | direct | 片內RAM低128字節 特殊功能寄存器SFR |
| 寄存器間址 | @R0,@R1,SP @R0,@R1,@DPTR | 片內RAM 片外RAM與I/O口 |
| 立即尋址 | #data | 程序存儲器 |
| 基址加變址 | @A+PC @A+DPTR | 程序存儲器 |
| 相對尋址 | PC+rel | 程序存儲器 |
| 位尋址 | bit | 片內RAM的20H~2FH 可位尋址的SFR |
3.MCS-51 單片機的指令系統
在MCS-51單片機的指令中:操作碼占1字節;
-
操作數中:
- 直接地址direct占1字節
- #data占1字節
- #data16占兩字節
-
A、B、R0~R7、@Ri、@DPTR、@ A+ DPTR、 @ A+ PC等均隱含在操作碼中(由操作碼中的幾位二進制位表示)。
1.數據傳送指令
所謂數據“傳送”,就是把源操作數傳送到目的寄存器或RAM單元中,指令執行后一般源地址單元內容不變,屬於“復制”而不是“剪切”;或者源操作數與目的地址單元內容互換(交換指令)。
數據傳送指令共29條,可分為五類:
-
內部RAM或寄存器間的數據傳送(16條)MOV
-
累加器A與外部RAM間的數據傳送(4條)
-
累加器A與程序存儲器間的數據傳送(2條)
-
數據交換(5條)
-
堆棧操作(2條)

1.內部RAM或寄存器間的數據傳送(16條) MOV
| 指令格式 | 舉 例 | 指令功能 |
|---|---|---|
| MOV A,#data | MOV A,#25H | 將立即數25H送至A |
| MOV A,Rn | MOV A,R3 | 將寄存器R3中的內容送至A |
| MOV A,direct | MOV A,45H | 將45H單元的內容送至A |
| MOV A,@Ri | MOV A,@R0 | 將寄存器R0所指的內存單元內容送至寄存器A |
| MOV direct,#data | MOV direct,#22H | 將立即數22H送RAM區direct單元 |
| MOV direct,A | MOV 22H,A | 將A中的內容送至40H單元 |
| MOV direct,Rn | MOV 23H,Rn | 將寄存器Rn中的內容送至23H單元 |
| MOV direct,@Ri | MOV 24H,@Ri | 將Ri所指單元的內容送至24H單元 |
| MOV direct,direct2 | MOV 30H,40H | 將40H單元的內容送至30H單元 |
| MOV Rn,#data | MOV R6,#66H | 將8位立即數66H送至R6 |
| MOV Rn,A | MOV R7,A | 將A中的內容送至寄存器R7 |
| MOV Rn,direct | MOV R4,60H | 將60H單元的內容送至寄存器R4 |
| MOV @Ri,#data | MOV @R0,#25H | 將8位立即數25H送至R0所指的RAM單元中 |
| MOV @Ri,A | MOV @R1,A | 將A中的內容送至R1所指的RAM單元 |
| MOV @Ri, direct | MOV @R0, 25H | 將25H單元的內容送至R1所指的RAM單元 |
| MOV DPTR , #data16 | MOV DPTR , #2300H | 將16位立即數2300H送至數據指針寄存器 |
-
注意事項:
-
1.立即數是一個不帶符號的8位常數,且立即數不能作目的操作數;
-
2.direct表示的是8位直接地址,以此指出8051中128個RAM單元和128-255之間的特殊功能寄存器。但是要注意在128-235區有很多單元是空的寫入空單元的數將被丟掉,從空單元讀取的數無意義。
-
3.通用寄存器之間不允許直接傳送;
-
4.通用寄存器與寄存器間接尋址的RAM單元之間不能直接傳送;
錯誤的: MOV Rn,Rn MOV @Ri, @Ri MOV Rn, @Ri MOV #data, A -
5.在指令格式中,立即數尋址和直接尋址的表示方式不同。
MOV A,#40H 立即數40H送A MOV A,40H 40H單元的內容送A MOV 40H,#40H 將立即數40H送40H單元
-
2.累加器A與外部RAM間的數據傳送(4條) MOVX
- CPU與外部數據存儲器或外部擴展的I/O口之間進行數據傳送時,必須使用外部傳送指令MOVX。
- 外部數據傳送必須通過累加器A,且只能采用寄存器間接尋址(用R0, R1和DPTR三個間接尋址的寄存器)方式完成。
| 匯編語言指令 | 舉例 | 指令功能 |
|---|---|---|
| MOVX A, @Ri | MOVX A, @R1 | 將R1所指的外部存儲器單元的內容送A |
| MOVX A, @DPTR | MOVX @R0,A | 將A中的內容送至Ri所指的外部存儲器單元 |
| MOVX @Ri, A | MOVX A,@DPTR | 將16位指針DPTR所指的外部存儲器單元的內容送至A |
| MOVX @DPTR, A | MOVX @DPTR,A | 將A中的內容送至DPTR所指的外部存儲器單元 |
- 例.下列指令執行完之后,累加器A和外部RAM 1234H單元內容分別是多少?
MOV 30H,#44H ;(30H)=44H
MOV R1,#30H ;(R1)=30H
MOV A,@R1 ;(A)=44H
MOV DPTR,#1234H ;(DPTR)=1234H
MOVX @DPTR,A ;(1234H)=(A)=44H
執行完上述指令之后,(A)=44H,(1234H)=44H
- 注意:
- 由於Ri是8位的寄存器,所以只能訪問片外RAM的一頁中的256個單元,頁內偏移地址00H~0FFH放在Ri中,頁地址先由P2口輸出。
- DPTR可以訪問片外RAM的全部64KB的空間。
3.累加器A與程序存儲器間的數據傳送(2條)MOVC
- MCS-51單片機的程序存儲器內的數據是只讀的,因此程序存儲器的數據傳送是單向的,並且只能讀到累加器A中。這類指令在查表中經常用到,所以又稱為查表指令。查表指令一共有2條,都屬於基址加變址尋址。
| 編語言指令 | 機器碼 | 指令功能 |
|---|---|---|
| MOVC A , @A+DPTR | 1001 0011 | 將DPTR中的16位地址和A中的內容相加得新地址,將此地址單元中的內容送至A中 |
| MOVC A , @A+PC | 1000 0011 | 將PC和A中的內容相加,所得的值作為新的地址,將此地址的內容送至A中 |
- 【例】將外ROM 1234H單元中的數據傳送至內RAM的30H單元中。
解法:
MOV DPTR,#1234H ;將16位立即數1234H送至數據指針寄存器
MOV A,#00H ;將立即數00H送至A中
MOVC A,@A+DPTR ;將DPTR中的16位地址和A中的內容相加得新地址,將此地址單元中的內容送至A中
MOV 30H,A ;將A中的數據傳送至內RAM的30H單元中
4.數據交換指令(5條)XCH XCHD SWAP
- 1)半字節數據交換指令(2條)
| 匯編語言指令 | 機器碼 | 指令功能 |
|---|---|---|
| SWAP A | 1100 0100 | 將A的高四位和低四位交換 |
| XCHD A, @Ri | 1101 011i | Ri為R0或R1,將Ri所指單元的低4位與A的低4位互換,高4位不變 |
注:XCHD A, @Ri 指令對P標志位有影響。
- 2)整字節交換指令(3條)
| 匯編語言指令 | 機器碼 | 指令功能 |
|---|---|---|
| XCH A,Rn | 1100 1rrr | Rn為R0~R7之一,將工作寄存器Rn的內容和A的內容交換 |
| XCH A,direct | 1100 0101 direct | 將 direct單元內容和A的內容交換 |
| XCH A,@Ri | 1100 011i | Ri為RO或R1,將Ri所指單元的內容和A的內容互換 |
- 例1.A中為1110 0110,則執行SWAP A 后,A中為0110 1110。
- 例2.已知(A)=12H、(R1)=30H、(30H)=34H,分析指令執行的結果。
- XCHD A, RI
解:(A)=14H、(30H)=32H,R1內容仍然保持不變。
- 例3.已知(A)=12H、(R1)=30H、(30H)=34H,分析指令執行的結果。
- XCH A. @ RI
解:(A)=34H、(30H)=12H,R1內容保持不變。
5.堆棧操作指令(2條)PUSH POP
| 匯編語言指令 | 機器碼 | 指令功能 |
|---|---|---|
| PUSH direct | 1100 0000 direct | SP←(SP)+1 (SP)←(direct) |
| POP direct | 1101 0000 direct | direct←((SP)) SP←(SP)-1 |
- PUSH DPH:先將SP加1,再將數據指針高位DPH推入堆棧SP+1單元;
- PUSH DPL:先將SP加1,再將數據指針低位DPL推入堆棧SP+1單元;
- PUSH direct:先將SP加1,再將direct所指單元內容推入SP+1所指的堆棧單元;
- POP direct:先將SP單元的內容彈出到 direct單元,再將SP減1;
- POP DPH:先將棧頂SP的內容彈出到數據指針的高8位DPH,再將SP減1;
- POP DPL:先將棧頂SP的內容彈出到數據指針的低8位DPL,再將SP減1。
- 例.分析下面程序的執行結果,假設(30H)=55H,(40H)=AAH。
PUSH 30H
PUSH 40H
POP 30H
POP 40H
解:程序執行后(30H)=AAH,(40H)=55H
注意: 堆棧操作指令的操作數只能使用直接尋址,直接地址不能是寄存器名,因此應注意指令的書寫格式。
- 例如:
- PUSH ACC ;(不能寫成PUSH A)
- POP 00H ; (不能寫成POP R0)
2.算術運算指令
- 算術運算指令主要完成加、減、乘、除四則運算,以及加1、減1、BCD碼調(十進制調整)指令整等。
- 加減運算指令的兩個操作數中,目的操作數必須為累加器A;源操作數可以為Rn或@Ri(片內RAM)以及direct,或是#data,大多數都要影響到程序狀態字PSW,乘除指令不影響AC標志位。
以下8條指令對PSW中的所有標志位均產生影響!!!
- 不帶進位的加法指令(4條)
| 匯編語言指令 | 舉 例 | 指令功能 |
|---|---|---|
| ADD A , #data | ADD A,#23H | 將立即數23H和A相加,結果送至A |
| ADD A, direct | ADD A,40H | 將40H單元的內容和A相加,結果送至A |
| ADD A , Rn | ADD A,R3 | 將A的內容和R3的內容相加,結果送至A |
| ADD A , @Ri | ADD A,@R0 | 將A的內容和R0所指的片內RAM單元的內容相加,結果送至A |
例.分析下面的程序段的功能。
MOV A,#85H
ADD A,#97H
MOV 50H,A
解:
1000 0101 ===> 85H
+ 1001 0111 ===> 97H
---------------
1 0001 1100 ===> 11EH
解析:指令的功能是將85H和97H相加,並把相加的結果傳送到50H單元中,且相加后的進位標志Cy的為1
- 加法指令影響PSW的進位標志Cy。如果最高位(D7)有進位,則Cy=1;否則Cy=0。
- 例如,在85H+97H后最高位有進位,(Cy)=1。
- 如果低4位有進位(即D3向D4進位),則輔助進位標志AC=1,否則AC=0。
- 如果相加以后,D7、D6中只有一位有進位則溢出標志OV=1;若D7、D6中均有進位或均無進位,則溢出標志OV=0;
- 若A中“1”的個數為偶數,則P=0,否則,P=1。
【例1】請分析執行如下程序段后A、Cy、AC、OV的結果。
1)MOV A,#00110110B
ADD A,#00110101B
解:指令執行后 (A)=6BH、(Cy)=0、(AC)=0、(OV)=0
2)MOV A,#11010001B
ADD A,#01011001B
解:指令執行后 (A)=2AH、(Cy)=1、(AC)=0、(OV)=0
3)MOV A,#10010010B
ADD A,#11001001B
解:指令執行后 (A)=5BH、(Cy)=1、(AC)=0、(OV)=1
4)MOV A,#0110011B
ADD A,#00110110B
解:指令執行后 (A)=9DH、(Cy)=0、(AC)=0、(OV)=1
- 帶進位的加法指令(4條)
| 匯編語言指令 | 舉 例 | 指令功能 |
|---|---|---|
| ADDC A , #data | ADDC A,#23H | A←(A)+data+( Cy) |
| ADDC A, direct | ADDC A,40H | A←(A)+ (direct) +( Cy) |
| ADDC A , Rn | ADDC A,R3 | A←(A)+(Rn) +( Cy) |
| ADDC A , @Ri | ADDC A,@R0 | A←(A)+((Ri)) +( Cy) |
- 與ADD指令的唯一區別是:ADDC指令除了降至零中規定的兩個操作數相加外,還要加上進位標志位Cy的值。此處的Cy的值是指令執行前的進位標志位的內容,不是相加后產生的Cy的值。
【例2】已知當前(Cy)=1,分析下列指令執行后,A與PSW相關標志位的結果。
MOV A,#85H
ADDC A,#97H
解:(A)=1DH、(Cy)=1、(AC)=0、(OV)=1、(P)=0
【例3】編寫程序,將內RAM 30H與50H為起始單元的單元2B無符號數相加,並將結果存放到30H為起始地址的區域中。設30H、50H是操作數的低字節。
解:
MOV A,30H
ADD A,50H
MOV 30H,A
MOV A,31H
ADDC A,51H
MOV 31H,A
MOV A,#00H
ADDC A,#00H
MOV 32H,A
【例4】將內RAM 20H單元、21H單元、22H單元中的三個無符號數相加,並將和存入R0(高位)與R1(低位)。
解:
MOV A,20H ;把20H單元內容存入A
ADD A,21H ;把21H單元的內容和A中單元內容(即20H)相加
MOV R1,A ;將前兩個數相加的低位存入R1
MOV A,#00H ;給A賦值為0
ADDC A,#00H ;將前兩個數相加的進位存入A
MOV R0,A ;將前兩個數相加的高位(進位)存入R0
MOV A,R1 ;將前兩個數相加的低位存入A
ADD A,22H ;前兩個數相加的低位與第三個數相加
MOV R1,A ;三個數和的低位存入R1
MOV A,#00H ;給A賦值為0
ADDC A,R0 ;第二次加法的進位與第一次加法的高位(R0中的數)相加
MOV R0,A ;高位和存入R0
- 帶借位的減法指令(4條)
| 匯編語言指令 | 指令功能 | 舉 例 |
|---|---|---|
| SUBB A , #data | A←(A)-data- (Cy) | SUBB A , #10H |
| SUBB A, direct | A←(A) - (direct) - (Cy) | SUBB A, 50H |
| SUBB A , Rn | A←(A) - (Rn) - (Cy) | SUBB A , R3 |
| SUBB A , @Ri | A←(A) - ((Ri)) - (Cy) | SUBB A , @R0 |
- MCS-51指令系統中沒有不帶借位的減法,因此要實現不帶借位的減法,需在執行SUBB指令前,應使用指令CLR C 對Cy清零。
- 它對PSW中的所有標志位均產生影響。
【例】.已知(Cy)=1,分析下面指令的執行結果。
MOV A,#79H
SUBB A,#56H
解:
0111 1001
- 0101 0110
----------------
0010 0010
指令執行后,累加器A的內容是22H,(Cy)=0、(AC)=0、(OV)=0、(P)=0
- 十進制調整指令(1條)
| 匯編語言指令 | 指令功能 | 舉 例 |
|---|---|---|
| DA A | 將A的內容調整為正確的BCD碼 | DA A |
- 十進制調整指令是一條專門用於對8421 BCD碼加法結果進行調整的指令,它跟在加法指令ADD或ADDC后面,對BCD碼數的和進行BCD碼修正。
- BCD碼調整的原則:
- ① 若累加器A的低4位大於9或(AC)=1,則(A)=(A)+06H;
- ② 若累加器A的高4位大於9或(Cy)=1,則(A)=(A)+60H;
- 它對PSW中除OV之外的的所有標志位均產生影響。
- 另外,十進制調整指令不能對減法指令進行修正。BCD碼減法必須采用BCD補碼運算法則,變減法為補碼加法(被減數+減數的補碼,單字節減數的補碼=9AH-減數),然后對其進行十進制調整來實現。
【例】試編寫程序求68H和99H這兩個數的BCD碼之和。
解:
MOV A,#68H ;(A)=68H
MOV R0,#99H ;(R0)=99H
ADD A,R0
;未調整時 (A)=01H,(Cy)=1,(AC)=1
DA A
;調整之后(A)=67H,(Cy)=1,結果為167,正確
- 加1指令(5條)
| 匯編語言指令 | 指令功能 | 舉 例 |
|---|---|---|
| INC A | A←(A)+1 | INC A |
| INC direct | direct←(direct)+1 | INC 30H |
| INC Rn | Rn←(Rn) +1 | INC R4 |
| INC @Ri | (Ri)←((Ri))+1 | INC @R0 |
| INC DPTR | DPTR←(DPTR)+1 | INC DPTR |
- 它只對PSW中的P標志位產生影響。
【例】編寫程序,將內RAM 30H為起始地址的3個無符號數相加,並將結果(假設結果小於100H)存放到40H單元中。
MOV A,#00H
MOV R0,#30H
ADD A,@R0
INC R0
ADDC A,@R0
INC R0
ADDC A,@R0
MOV 40H,A
- 減1指令(4條)
| 匯編語言指令 | 指令功能 | 舉 例 |
|---|---|---|
| DEC A | A←(A)-1 | DEC A |
| DEC direct | direct←(direct) -1 | DEC 50H |
| DEC Rn | Rn←(Rn) -1 | DEC R4 |
| DEC @Ri | (Ri)←((Ri)) -1 | DEC @R1 |
- 它只對PSW中的P標志位產生影響。
【例】編程實現DPTR減1的運算。
解:由於減1指令中沒有DPTR減1的指令,因此需要將DPTR拆分為DPH 和DPL來進行操作。
CLR C ;將Cy清零
MOV A,DPL ;將數據指針的低8位送入A
SUBB A,#01H ;將A的內容減1送入A
MOV DPL,A ;將A的內容減1送入DPL
MOV A,DPH ;將數據指針的高8位送入A
SUBB A,#00H ;將A的內容減0,再減去低位的借位送入A
MOV DPH,A ;將A中得到的最終結果送入DPH
- 乘除指令(2條)
| 匯編語言指令 | 機器碼 | 指令功能 |
|---|---|---|
| MUL AB | 1010 0100 | (B)(A)←(A) (B) |
| DIV AB | 1000 0100 | (A)←(A)/(B) (B)←(A)mod(B) |
- 一條乘法指令只能完成2個8位無符號數相乘,乘數和被乘數分別放在A和B寄存器中,乘積的高8位放在B寄存器中、低8位放在累加器A中;
- 一條除法指令只能完成2個8位無符號數相除,被除數和除數分別存放在A和B寄存器中,商存放在A中,余數存放在B中。
【例】分析下面指令的執行結果
MOV A,#36H
MOV B,#03H
MUL AB
解:
0011 0110
x 0000 0011
---------------
0011 0110
0 0110 110
---------------
0 1010 0010
結果:(A)=0A2H、(B)=00H、(Cy)=0、(OV)=0、(P)=1
【例】分析下面指令執行結果
MOV A,#87H
MOV B,#0CH
DIV AB
解:(A)=0BH、(B)=03H、(Cy)=0、(OV)=0、(P)=1
3.邏輯運算和移位指令
- 常用的邏輯運算和移位類指令有: 邏輯與、邏輯或、邏輯異或、循環移位、清零、求反等指令,它們的操作數都是8位的。
- 邏輯運算都是按位進行的。
- 邏輯運算和移位指令中,以A為目的操作數的指令影響P標志位,帶進位的循環移位指令影響Cy和P標志位,其余均不影響PSW各標志位。
- 邏輯與運算指令(6條)
| 匯編語言指令 | 指令功能 | 舉 例 |
|---|---|---|
| ANL A ,#data | A←(A) data | ANL A ,#0F0H |
| ANL A , direct | A←(A) (direct) | ANL A , 50H |
| ANL A , Rn | A←(A) (Rn) | ANL A , R3 |
| ANL A , @Ri | A←(A) ((Ri)) | ANL A , @R1 |
| ANL direct ,A | direct←(A) (direct) | ANL 40H ,A |
| ANL direct,#data | direct←(direct) (data) | ANL 55H,#55H |
注:邏輯與的規則為“見0為0,全1為1”。
- 邏輯或運算指令(6條)
| 匯編語言指令 | 指令功能 | 舉 例 |
|---|---|---|
| ORL A, #data | A←(A) data | ORL A ,#0F0H |
| ORL A, direct | A←(A) (direct) | ORL A , 50H |
| ORL A, Rn | A←(A) (Rn) | ORL A , R3 |
| ORL A, @Ri | A←(A) ((Ri)) | ORL A , @R1 |
| ORL direct, A | direct←(A) (direct) | ORL 40H ,A |
| ORL direct, #data | direct←(direct) (data) | ORL 55H,#55H |
注:邏輯或的規則為“見1為1,全0為0”。
- 邏輯異或運算指令(6條)
| 匯編語言指令 | 指令功能 | 舉 例 |
|---|---|---|
| XRL A, #data | A←(A) data | XRL A ,#0F0H |
| XRL A, direct | A←(A) (direct) | XRL A , 50H |
| XRL A, Rn | A←(A) (Rn) | XRL A , R3 |
| XRL A, @Ri | A←(A) ((Ri)) | XRL A , @R1 |
| XRL direct, A | direct←(A) (direct) | XRL 40H ,A |
| XRL direct, #data | direct←(direct) (data) | XRL 55H,#55H |
注:邏輯異或的規則為“相同為0,相異為1”。
- 循環移位指令(4條)
- MCS-51單片機的循環移位指令共有4條:
- ①不帶進位的循環左移指令RL;
- ②不帶進位的循環右移指令RR;
- ③帶進位的循環左移指令RLC;
- ④帶進位的循環右移指令RRC。
- 它們都只能對累加器A進行移位。
- 使用移位指令可以實現乘法或除法:
- 左移一位相當於乘2;
- 右移一位相當於除2。
| 匯編語言指令 | 指令功能 |
|---|---|
| RL A | ![]() |
| RR A | ![]() |
| RLC A | ![]() |
| RRC A | ![]() |
- 累加器清零與取反指令(2條)
| 匯編語言指令 | 指令功能 |
|---|---|
| CLR A | A←0 |
| CPL A | A←(A) |
- 利用取反,可以進行求補操作,即對要求補的數先取反再加 1。
4.控制轉移指令
- 計算機在運行的過程中,一般通過程序計數器PC的自動加1實現順序執行,有時候對於較復雜的操作,需要通過強迫改變PC值的方法來進行程序的分支轉移,這就需要用到控制轉移指令。
- 控制轉移指令的功能——通過改變程序計數器PC中的內容,控制程序執行的流程,實現程序分支轉向。
- MCS-51單片機提供了17條控制轉移指令。
- 無條件轉移指令(4條)
| 匯編語言指令 | 機器碼 | 指令功能 |
|---|---|---|
| LJMP addr16 | 0000 0010 addr15~8 addr7~0 | PC←addr15~0 |
| AJMP addr11 | A10A9A80 0001 A7~A0 | PC←(PC)+2, PC 10~0←addr11 |
| SJMP rel | 1000 0000 rel | PC←(PC)+rel |
| JMP @A+DPTR | 0111 0011 | PC←(DPTR)+(A) |
1)長轉移指令(LJMP addr16)
- 長轉移指令提供了16位的目標轉移地址,其功能是把指令碼中的16位轉移目標地址送入PC,因此這條指令可以跳轉到64KB ROM的任意位置。
- 為了方便,程序中addr16通常采用符號地址表示,匯編時再被匯編成16位二進制地址,所以該指令的使用格式通常為:
LJMP 標號
2)絕對轉移指令(AJMP addr11)
-
這條指令可以在該指令的下一條指令的同一個2KB區域(211)內跳轉。PC15~PC11用於把64KB的ROM划分為32個區域,相當於32個頁(每頁2KB,由PC10~PC0確定)。
-
指令執行時,用指令碼中的11位地址替換當前PC值(AJMP的下一條指令的地址)的低11位,當前PC值的高5位不變。
-
在實際程序設計中,addr11也常用標號代替,程序匯編時再被自動匯編成對應的11位地址。該指令的使用格式通常為:
AJMP 標號
3)相對(短)轉移指令(SJMP rel)
- 執行本指令時,轉移的目標地址為(PC)=(PC)+rel,rel是一個用補碼表示的8位帶符號二進制數,范圍為-128~+127,負數表示向前(地址變小方向)轉移,正數表示向后(地址變大方向)轉移。
- 程序中,rel常用符號地址表示,因此,該指令的常用格式為:
SJMP 標號
- 機器匯編時由匯編程序自動計算出rel的值,手工匯編時,需要人工計算rel的值:
rel=目標標號的地址-當前的PC值
- 在編程中,經常使用短轉移指令SJMP和絕對轉移指令AJMP,以便生成浮動代碼。
- 另外,MCS-51單片機無專用的停機指令,若要求動態停機(不想單片機繼續往下執行)可用SJMP指令,常用方法有以下兩種:
- 方法1:
HERE :SJMP HERE - 方法2:
SJMP $
- 方法1:
4)間接(散)轉移指令(JMP @A+DPTR)
- 功能:把累加器A中的8位無符號數與數據指針DPTR中的16位數相加,其結果送入PC,作為轉移的目標地址,利用這條指令能實現程序的散轉。
- 散轉指令可以在不需要判斷的情況下實現程序的多分支轉移。
- 例2. 分析下面程序的執行過程。
MOV DPTR,#TAB ;將TAB所代表的地址送入DPTR
MOV A,R1 ;從R1中取數送入A
MOV B,#2 ;給B賦值為2
MUL AB ;A中的數(即原來R1中的數)乘以2
JMP @A+DPTR ;跳轉
TAB: SJMP S0 ;跳轉表格,S0處理程序
SJMP S1 ;S1處理程序
SJMP S2 ;S2處理程序
- 條件轉移指令(8條)
-
條件轉移指令的功能:在規定的條件滿足時進行程序轉移,否則程序往下順序執行。
-
MCS-51單片機中,條件轉移指令有:
- 累加器A判零轉移指令(JNZ/JZ)
- 比較不相等轉移指令(CJNE)
- 減1不為0轉移指令(DJNZ)(循環控制指令)
1)累加器A判零轉移指令(2條)
| 匯編語言指令 | 機器碼 | 指令功能 |
|---|---|---|
| JZ rel | 0110 0000 rel | 若(A)=0,則轉移(PC)←(PC)+rel; 若(A)≠0,則順序執行 |
| JNZ rel | 0111 0000 rel | 若(A)≠0,則(PC)←(PC)+rel; 若(A) =0,則順序執行 |
2)比較轉移指令(4條)
| 匯編語言指令 | 機器碼 | 指令功能 |
|---|---|---|
| CJNE A, direct, rel | 10110101 direct rel | 若(A)=(direct),則順序執行; 若(A)>(direct),則(PC)←(PC)+rel,Cy= 0; 若(A) <(direct),則(PC)←(PC)+rel,Cy= 1 |
3)減1不為0轉移指令(循環控制指令)(2條)
| 匯編語言指令 | 機器碼 | 指令功能 |
|---|---|---|
| DJNZ Rn, rel | 1101 1rrr rel | (Rn)←(Rn)-1, 若(Rn)≠0則 (PC) ←(PC)+rel 若(Rn)=0則順序執行 |
- 例3. 編程計算1+2+3+……+10的值。
解:本題目為自然數依次相加,從1加到10,故可以用循環指令來控制循環次數。
程序如下:
MOV R0,#10 ;設置循環次數
CLR A ;累加器清零
LOOP:ADD A,R0 ;循環體
DJNZ R0,LOOP ;控制循環次數
SJMP $ ;結束
- 子程序調用與返回指令(4條)
- 在程序運行時,可以通過調用指令來調用並執行子程序;子程序執行完后,再用返回指令從子程序返回到主程序。
- 為了實現子程序的完整調用,子程序調用指令和返回指令必須成對出現。
- 子程序可以嵌套,即在一個子程序執行過程中可以調用另外的子程序,形成子程序的嵌套。子程序嵌套有利於模塊化程序設計。

| 匯編語言指令 | 機器碼 | 指令功能 |
|---|---|---|
| LCALL addr16 | 0001 0010 addr15~8 addr7~0 | (PC)←(PC)+3, SP←(SP)+1,(SP)←(PC)7~0; SP←(SP)+1,(SP)←(PC)15~8, (PC)15~0←addr16 |
1)長調用指令 LCALL
- 長調用指令,用於調用存放在 64KB 空間任意地方的子程序,本指令不影響 PSW 的各標志位。
- 使用格式為:LCALL 標號(標號即為子程序名)。
2)短調用指令 ACALL
- 該指令的調用范圍為 2KB,執行該指令時共完成 2 項操作:
- ① 斷點保護,即通過自動入棧,把斷點地址((PC)+2 的值)保存起來;
- ② 構造目的地址,即用 addr11 代替當前 PC的低 11 位,而 PC 的高 5 位不變。
- 子程序必須存放在該指令的下一條指令的第一個字節開始 的 2KB 范圍內,即同一頁內。
- 該指令的使用格式為:ACALL 標號(標號即為子程序名)。
3)子程序返回指令 RET
- 該指令與子程序調用指令成對出現,其功能是從堆棧中取出斷點地址,送入 PC,使主程序從斷點(調用指令的下一條指令)處繼續執行。
4)中斷返回指令 RETI
- 中斷服務程序是一種特殊的子程序,它是在計算機響應中斷時,由硬件完成調用而進入相應的中斷服務程序。
- RETI 指令與 RET 指令的區別在於 RETI 在從中斷服務程序返回時,還要對相應優先級的中斷觸發器清 0。無論是 RET 還是 RETI 都是子程序執行的最后一條指令。
- 空操作指令
| 匯編語言指令 | 機器碼 | 指令功能 | 指令字節數 | 機器周期數 |
|---|---|---|---|---|
| NOP | 0000 0000 | PC←PC+1,空操作 | 1 | 1 |
- 空操作指令不進行任何操作,但要占一個字節的空間,執行時要占用一個機器周期,多用於延時等待或在抗干擾設計中做指令冗余,以提高軟件的可靠性。
5.位操作指令
- 位操作指令操作對象是某個可尋址的位,由於位的取值只能是0或1,故位操作指令又稱為布爾變量操作指令。
- 位操作指令操作的對象——片內RAM的128個可尋址的位和SFR中11個可位尋址的特殊功能寄存器中的82個可尋址位。
- 位操作指令以進位標志Cy作為位累加器(C),可以實現布爾變量的傳送、運算和控制轉移等功能。
- 位數據傳送指令(2 條)
- 位數據傳送可以在可尋址位與位累加器 C 之間進行,以 C 做中介可以實現兩個位之間的數據傳送。
| 匯編語言指令 | 指令功能 | 舉 例 |
|---|---|---|
| MOV C ,bit | C← (bit) | MOV C ,20H MOV C ,P0.2 |
| MOV bit , C | bit ← © | MOV 20H,C MOV P0.2,C |
- 位狀態控制指令(4 條)
- 位狀態控制主要是對位置位或復位。
| 匯編語言指令 | 指令功能 | 舉 例 |
|---|---|---|
| CLR C | C ← 0 | CLR C |
| CLR bit | bit ← 0 | CLR 30H CLR EA |
| SETB C | C ← 1 | SETB C |
| SETB bit | bit ← 1 | SETB 30H SETB EA |
- 位邏輯操作指令(6 條)
- 位邏輯操作有位與、位或、位異或、位取反等,除了位取反指令 CPL bit 外,其余指令均以位累加器 C 為目的操作數,執行結果存入 C,原位的內容不發生變化。
| 匯編語言指令 | 指令功能 | 機器周期數 |
|---|---|---|
| ANL C ,bit | C ←© ∧ (bit) | ANL C ,30H |
| ANL C ,/bit | C ←© ∧ (bit) | ANL C ,/30H |
| ORL C,bit | C ←© ∨ (bit) | ORL C,30H |
| ORL C ,/bit | C ←© ∨ (bit) | ORL C ,/30H |
| CPL C | C ← © | CPL C |
| CPL bit | (bit) ← (bit) | CPL TR0 |
例:用軟件實現下圖所示的P1.0 ~ P1.3間的邏輯運算。
MOV C,P1.1
ORL C,P1.2
ANL C,P1.0
MOV P1.3,C

- (P1.1 ≥ P1.2) & P1.0
例3.25 設x, y, z為不同的位地址,編程實現(z)=(x) ⊕ (y)
解 析 : M O V C , y ; ( C ) = ( y ) A N L C , / x ; ( C ) = ( y ) ∧ ( x ˉ ) M O V Z , C ; ( z ) = ( C ) = ( y ) ∧ ( x ˉ ) M O V C , x ; ( C ) = ( x ) A N L C , / y ; ( C ) = ( x ) ∧ ( y ˉ ) O R L C , Z ; ( C ) = ( y ) ∧ ( x ˉ ) + ( x ) ∧ ( y ˉ ) M O V Z , C ; ( Z ) = ( y ) ∧ ( x ˉ ) + ( x ) ∧ ( y ˉ ) = ( x ) ⊕ ( y ) \begin{aligned} 解析: &MOV \quad C,y \quad ;(C)=(y) \\ &ANL \quad C,/x \quad ;(C)=(y) ∧ ( \bar{x} ) \\ &MOV \quad Z,C \quad ;(z)=(C)=(y)∧ (\bar{x} )\\ &MOV \quad C,x \quad ;(C)=(x) \\ &ANL \quad C,/y \quad ;(C)=(x) ∧ ( \bar{y} )\\ &ORL \quad C,Z \quad ;(C)=(y) ∧ ( \bar{x} )+(x)∧ (\bar{y} ) \\ &MOV \quad Z,C \quad ;(Z)=(y) ∧ ( \bar{x} )+(x)∧ (\bar{y} )=(x) ⊕ (y)\\ \end{aligned} 解析:MOVC,y;(C)=(y)ANLC,/x;(C)=(y)∧(xˉ)MOVZ,C;(z)=(C)=(y)∧(xˉ)MOVC,x;(C)=(x)ANLC,/y;(C)=(x)∧(yˉ)ORLC,Z;(C)=(y)∧(xˉ)+(x)∧(yˉ)MOVZ,C;(Z)=(y)∧(xˉ)+(x)∧(yˉ)=(x)⊕(y)
- 位條件(控制)轉移指令(5 條)
- 位條件(控制)轉移指令和前面介紹過的條件轉移指令類似,只不過是以位的狀態作為 程序轉移的判斷條件,可以使程序設計更加方便、靈活。
| 匯編語言指令 | 指令功能 | 舉 例 |
|---|---|---|
| JC rel | 若©=1,則轉移(PC)←(PC)+rel ; 否則順序執行 | JC NEXT |
| JNC rel | 若©=0,則轉移(PC)←(PC)+rel; 否則順序執行 | JNC NEXT |
| JB bit , rel | 若(bit)=1,則轉移(PC)←(PC)+rel; 否則順序執行 | JB F0,NEXT |
| JNB bit , rel | 若(bit)=0,則轉移(PC)←(PC)+rel; 否則順序執行 | JNB F0,NEXT |
| JBC bit , rel | 若(bit)=1,則轉移(PC)←(PC)+rel,且(bit )←0; 否則順序執行 | JBC F0,NEXT |
例3.26 求出內RAM30H單元中的數據含1的個數,並將結果存入31H單元。
解:
CLR C ;C清零
MOV R2,#8 ;設置循環次數
MOV R1,#00 ;計數單元清零
MOV A,30H ;把30H單元內容讀入A
LOOP:RRC A ; 將(ACC.0)循環移入Cy中
JNC NEXT ;Cy中不為1則轉至NEXT
INC R1 ;若Cy為1,則R1內容加1
NEXT:DJNZ R2,LOOP ; 8不夠則繼續執行移位
MOV 31H,R1 ;將計數結果送入31H單元
SJMP $ ;停機(原地踏步)
END ;結束




