ĐHBK Tp HCM
Khoa ĐĐT–BMĐT
GVPT: Hồ Trung Mỹ
Các TD minh họa tập lệnh 8051 (phần đọc thêm của VXL-chương 3)
Chú ý: Các TD sau sẽ trình bày theo thứ tự giới thiệu các nhóm lệnh trong sách VXL, như arith01.asm để chỉ
TD 1 với nhóm lệnh số học, và 1 nhóm lệnh có thể có nhiều TD minh họa.
TD : Minh họa các phép toán số học trên số nhị phân: ADD, ADDC, SUBB, INC, DEC, MUL, và DIV
; TD: arith01.asm
; Định nghĩa các hằng số dùng trong chương trình
NUM1 EQU 25 ; = 19H
NUM2 EQU -17 ; = EFH
NUM2M EQU 20h ; Địa chỉ ở IRAM (RAM nội) có trị số bằng NUM2
BIN16_1 EQU 2578 ; = 0A12H
BIN16_2 EQU 1289 ; = 0509H
SUM16M EQU 22H ; Địa chỉ ở IRAM chứa tổng 2 số nhị phân 16 bit
DIFF16M EQU 24H ; Địa chỉ ở IRAM chứa hiệu 2 số nhị phân 16 bit
; = BIN16_2 - BIN16_1 = -1289 = FAF7H
TEST EQU 1289-2578 ; = FAF7H
org 0
; Thử lệnh ADD với toán hang 8 bit ( toán hạng thứ 2 la hằng số)
MOV A,#NUM1
ADD A,#NUM2 ; A <- A + NUM2 = 25 + (-17) = 8 = 0000 1000
; Ảnh hưởng đến các cờ:
; lúc này PSW = C1h = 1100 0001 (tương ứng các bit C,AC,F0,RS1,RS0,OV,-,P)
; Khi cộng nhị phân cho C = 1, AC =1 (có nhớ ở bit 4), RS1=RS0=0 sau khi RESET
; OV = C XOR C
MSB
= 1 XOR 1 = 0, P = 1 do so bit 1 trong ACC là lẽ
; Chú ý: Chương trình mô phỏng TS Controls Emulator 8051 tính sai OV!!!
; Thu lenh ADD voi toan hang 8 bit ( toan hang thu 2 la thanh ghi B)
MOV A,#NUM1
MOV B,#NUM2
ADD A,B ; A <- A + B = 25 + (-17) = 8
; Thu lenh ADD voi toan hang 8 bit ( toan hang thu 2 la thanh ghi da dung Rn)
MOV A,#NUM1
MOV R0,#NUM2
ADD A,R0 ; A <- A + R0 = 25 + (-17) = 8
; Thử lệnh ADD với toán hang thứ 2 là 1 byte trong bộ nhớ nội
MOV NUM2M,#NUM2
MOV A,#NUM1
ADD A,NUM2M ; A <- A + (NUM2M) = 25 + (-17) = 8
; Thử lệnh ADD với toán hang thứ 2 là 1 byte trong bộ nhớ nội có pointer là R0
MOV R0,#NUM2M
MOV A,#NUM1
ADD A,@R0 ; A <- A + Mem(R0) = 25 + (-17) = 8
; Thử lệnh ADD với toán hang thứ 2 là 1 byte trong bộ nhớ CODE (bộ nhớ chương trình)
MOV DPTR,#NUM2C ; Lay dia chi cua bien NUM2C
CLR A
MOVC A,@A+DPTR
ADD A,#NUM1 ; A <- NUM2 + NUM1 = -17 + 25 = 8
; Thử lệnh ADD va ADDC -> cộng 2 hằng số 16 bit
; Kết quả cất vào ô nhớ dữ liệu nội SUM16M theo big endian
MOV A,#LOW BIN16_1 ; Lấy byte thấp của hằng số 16 bit
ADD A,#LOW BIN16_2
MOV SUM16M+1,A
MOV A,#HIGH BIN16_1 ; Lấy byte cao của hằng số 16 bit
ADDC A,#HIGH BIN16_2 ; Phai tinh den Carry cua phep cong truoc
MOV SUM16M,A ; (SUM16M) = 3987 = 0F1BH ( nghia la (22H)=0FH va (23H)=1BH
; Thu lenh SUBB voi 2 toan hang hang so 8 bit
MOV A,#NUM1
MOV B,#NUM2
CLR C
SUBB A,B ; A <- A - B = 25 - (-17) = 42 = 2AH
Các TD minh họa tập lệnh 8051 – trang 1
; Thu lenh SUBB voi 2 toan hang hang so 16 bit
; hieu 2 so nhi phan 16 bit = BIN16_2 - BIN16_1 = -1289 = FAF7H
; cat vao bien DIFF16M (24H)theo big endian
MOV A,#LOW BIN16_2 ; Lay byte thap cua hang so 16 bit
CLR C
SUBB A,#LOW BIN16_1
MOV DIFF16M+1,A
MOV A,#HIGH BIN16_2 ; Lay byte cao cua hang so 16 bit
SUBB A,#HIGH BIN16_1 ; Phai tinh den Carry cua phep cong truoc
MOV DIFF16M,A ; (DIFF16M) = 1289 - 2578 = -1289 = FAF7H
;(nghia la (24H)=FAH va (25H)=F7H
; Hiệu ứng của lệnh INC
INC A ; A <- A + 1
INC B ; B <- B + 1
MOV R0,#30H
INC @R0 ; Tăng byte với contrỏ R0 lên 1 (30H) = (30H) + 1
INC R0
INC @R0 ; (31H) = (31H) + 1
INC 0 ; 1 cach khac de co R0 <- R0 + 1
INC @R0 ; (32H) = (32H) + 1
INC DPTR
; Hieu ung cua lenh DEC
DEC A ; A <- A - 1
DEC B ; B <- B - 1
MOV R0,#30H
DEC @R0 ; Giam o nho duoc chi boi R0 di 1 (30H) = (30H) - 1
INC R0
DEC @R0 ; (31H) = (31H) - 1
DEC 0; 1 cach khac de co R0 <- R0 - 1
DEC @R0 ; (30H) = (30H) - 1
; Khong co lenh DEC DPTR !!!
; Do do ta phai dung doan chuong trinh sau de giam noi dung DPTR di 1
DEC DPL ; Giam byte thap cua DPTR di 1
MOV R7, DPL ; chép vào R7
CJNE R7, #0FFH, SKIP ; Neu tran duoi thành FF thì phai muon
DEC DPH ; do dó cung phai giam byte cao di 1
SKIP:
; Thu lenh nhan MUL voi 2 toan hang 8 bit: A x B
MOV A,#25
MOV B,#56
MUL AB ; B:A = 25 x 56 = 1400 = 478H ( B = 04H va A = 78H)
; Thu lenh chia DIV voi 2 toan hang 8 bit: A/B
MOV A,#255
MOV B,#7
DIV AB; A/B = 255/7 = 36 du so la 3 ==> A = 36 = 24H va B=03H
SJMP $ ; Nhảy tại chỗ
NUM2C: DB NUM2 ; Hằng số trong bộ nhớ CODE
END
TD : ; Minh họa các phép toán số học trên số BCD nén: ADD, ADDC
; TD: arith02.asm
BCD1_1 EQU 25H
BCD1_2 EQU 17H
BCD1_2M EQU 20h ; Dia chi o IRAM co tri so bang BCD1_2
BCD4_1 EQU 3456H
BCD4_2 EQU 6789H
SUM4M EQU 40H ; Dia chi o IRAM chua tong 2 so BCD 4 digit
org 0
; Thu lenh ADD voi toan hang BCD 2 digit ( toan hang thu 2 la hang so)
MOV A,#BCD1_1
ADD A,#BCD1_2 ; A <- A + BCD1_2 = 25H + 17H = 3CH
DA A ; A = 42H
Các TD minh họa tập lệnh 8051 – trang 2
; Thu lenh ADD voi toan hang BCD 2 digit ( toan hang thu 2 la thanh ghi B)
MOV A,#BCD1_1
MOV B,#BCD1_2
ADD A,B ; A <- A + B = 25H + 17H = 3CH
DA A ; A = 42H
; Thu lenh ADD voi toan hang BCD 2 digit ( toan hang thu 2 la thanh ghi da dung Rn)
MOV A,#BCD1_1
MOV R0,#BCD1_2
ADD A,R0 ; A <- A + R0 = 25H + 17H = 3CH
DA A ; A = 42H
; Thu lenh ADD voi toan hang thu 2 la so BCD 2 digit trong bo nho noi
MOV BCD1_2M,#BCD1_2
MOV A,#BCD1_1
ADD A,BCD1_2M ; A <- A + (BCD1_2M) = 25H + 17H = 3CH
DA A ; A = 42H
; Thu lenh ADD voi toan hang thu 2 la 1 byte trong bo nho noi co pointer la R0
MOV R0,#BCD1_2
MOV A,#BCD1_1
ADD A,@R0 ; A <- A + Mem(R0) = 25H + 17H = 3CH
DA A ; A = 42H
; Thu lenh ADD voi toan hang thu 2 la byte trong bo nho CODE
MOV DPTR,#BCD1_2C ; Lay dia chi cua bien BCD1_2C
CLR A
MOVC A,@A+DPTR
ADD A,#BCD1_1 ; A <- BCD1_2 + BCD1_1 = 25H + 17H = 3CH
DA A ; A = 42H
; Thu lenh ADD va ADDC -> cộng 2 số BCD 4 ký số
; Ket qua cat vao o nho du lieu noi SUM16M
MOV A,#LOW BCD4_1 ; Lay byte thap cua hang so 16 bit
ADD A,#LOW BCD4_2
DA A
MOV SUM4M+1,A
MOV A,#HIGH BCD4_1 ; Lay byte cao cua hang so 16 bit
ADDC A,#HIGH BCD4_2 ; Phai tinh den Carry cua phep cong truoc
DA A
MOV SUM4M,A
; Ket qua la 10245H voi C=1, (40H)=02H, va (41H) = 45H
; Chu y la DA A chi co tac dung sau lenh cong (ADD hay ADDC) ma thoi
; TD sau cho thay DA A voi lenh SUBB cho ket qua sai!
MOV A,#25H
MOV B,#17H
CLR C
SUBB A,B ; A <- A - B = 25H - 17H = 0EH
DA A ; A = 14H ==> Cho ket qua sai voi phep toan tru!!!
SJMP $
BCD1_2C: DB BCD1_2
END
TD : Minh họa các lệnh ANL, ORL, XRL (AND, OR, XOR với các toán hạng 8 bit)
; TD: logic01.asm
NUM1 EQU 15H ; 00010101B
NUM2 EQU 3AH ; 00111010B
; Thu lenh ANL voi toan hang 2 la hang so
MOV A,#NUM1
ANL A,#NUM2 ; A = 15H AND 3AH = 10H
; Thu lenh ANL voi toan hang 2 la byte o bo nho du lieu noi
MOV 20H,#24 ; (20H) = 24 = 18H
ANL A,20H ; A = 10H AND 18H = 10H
; ANL tuong tu voi cac toan hang 2 co dinh dia chi la REG, INDIRECT
; Ap dung ANL de giu lai cac bit can thiet (AND voi 1) va xoa cac bit khong can thiet ;
(AND voi 0)
MOV A,#NUM2 ; A =3AH
ANL A,#0FH ; A = 0AH = 4 bit thap
Các TD minh họa tập lệnh 8051 – trang 3
; Thu lenh ORL voi toan hang 2 la hang so
MOV A,#NUM1
ORL A,#NUM2 ; A = 15H OR 3AH = 3FH
; Ap dung ORL de dat 1 bit len 1 neu OR no voi 1 va giu tri cu neu OR voi 0
MOV A,#NUM1 ; A = 15H
ORL A,#0F0H ; A = F5H
; Thu lenh XRL voi toan hang 2 la hang so
MOV A,#NUM1
XRL A,#NUM2 ; A = 15H XOR 3AH = 2FH
; Ap dung XRL de lay NOT bit neu XOR no voi 1 va giu tri cu neu XOR voi 0
MOV A,#NUM1 ; A = 15H
XRL A,#0F0H ; A = E5H
MOV A,#NUM2 ; A = 3AH
XRL A,#0FFH ; A = bu 1 cua 3AH = C5H
INC A ; A = bu 2 cua 3AH = C6H
; Xoa noi dung thanh ghi A
CLR A ; A <- 0
; Cac cach khac de xoa A (khong hieu qua bang CLR)
MOV A,#0 ; hay
ANL A,#0
; Lấy bù 1 nội dung trong thanh ghi A
MOV A,#NUM2 ; A = 3AH
CPL A ; A = bù 1 của 3AH = C5H
XRL A,#0FFH ; A = bù 1 của C5H = 3AH (XRL không hiệu quả bằng CPL)
sjmp $
END
TD : Minh họa các lệnh xoay bit (Rotate) và hoán đổi 4 bit (SWAP)
; TD: logic02.asm
NUM1 EQU 15 ; 0000_1111B
NUM2 EQU -12 ; 1111_0100B
; Thu lenh RR A
MOV A,#NUM1 ; A = 0000_1111B = 0FH = 15
RR A ; A = 1000_0111B = 87H
RR A ; A = 1100_0011B = C3H
; Thu lenh RL A
MOV A,#NUM1 ; A = 0000_1111B = 0FH = 15
RL A ; A = 0001_1110B = 1EH = 30 = 15 x 2
1
RL A ; A = 0011_1100B = 3CH = 60 = 30 x 2 = 15 x 2
2
; Xoay phai voi co C
MOV A,#NUM1 ; A = 0000_1111B = 15
SETB C ; C <- 1
RRC A ; A = 1000_0111B = 87H va C = 1
; Xoay trai voi co C
MOV A,#NUM1 ; A = 0000_1111B = 15
SETB C ; C <- 1
RLC A ; A = 0001_1110B = 1EH va C = 0
; Ap dung dich phai de chia nguyen khong dau A cho 2
MOV A,#NUM1 ; A = 0000_1111B = 0FH = 15
RR A ; A = 1000_0111B = 87H
CLR ACC.7 ; A = 0000_0111B = 07H = 7 = 15/2
; Chia nguyen khong dau 1 so o A cho 2^n voi n = 1 -> 8
; n duoc dat trong thanh ghi R7
MOV R7,#2
MOV A,#00011111B ; A = 31
CALL DIV2EXPN ; A = 0000_0111B = 7 = 31 div 4
; Mot cach khac la dung lenh chia
MOV A,#31
MOV B,#4
DIV AB ; A = 31/4 = 7
Các TD minh họa tập lệnh 8051 – trang 4
; Ap dung dich phai voi C de chia nguyen co dau A cho 2
MOV A,#NUM2 ; A = -12 = F4H = 1111_0100B
MOV C,ACC.7 ; C = bit dau cua A
RRC A ; A = 1111_1010B = FAH = -6 va C=0
; Thử lệnh SWAP
MOV A,#47H
SWAP A ; A = 74H
sjmp $
DIV2EXPN: ; Chương trình con chia nguyên không dấu cho 2^n
RR A
CLR ACC.7
DJNZ R7, DIV2EXPn
RET
END
TD : Minh họa các lệnh chuyển dữ liệu: MOV, PUSH, POP, XCH, XCHD
; TD: mov01.asm
CONST1 EQU 15H
CONST2 EQU 27H
CONST3 EQU 36H
; Điền 16 byte trong vùng dữ liệu nội từ địa chỉ 30H voi tri so la CONST1
MOV A,#CONST1
MOV R0,#30H
MOV R1,#16
L1: MOV @R0, A
INC R0
DJNZ R1, L1
; Dien 32 byte trong vùng dữ liệu ngoại từ địa chỉ 20H voi tri so la CONST2
MOV A,#CONST2
MOV DPTR,#20H
MOV R1,#32
L2: MOVX @DPTR, A
INC DPTR
DJNZ R1, L2
; Dien 16 byte trong vung du lieu ngoai tu 40H voi tri so la CONST1
MOV A,#CONST3
MOV R0,#40H
MOV R1,#16
MOV P2,#0 ; Xuat byte cao dia chi
L3: MOVX @R0, A
INC R0
DJNZ R1, L3
; Hoán đổi (<-->)nội dung 2 ô nhớ trong RAM nội
; R1 <--> R7 ở bank 0
MOV R1,#CONST1 ; R1 = 15H
MOV R7,#CONST2 ; R7 = 27H
PUSH 07
PUSH 01
POP 07 ; R7 = 15h
POP 01 ; R1 = 27H
; Một cách khác để hoán đổi R1 va R7
XCH A,01H
XCH A,07H
XCH A,01H
; Hoan doi digit thap cua 2 so hex 2 ky so o A va 1 byte trong RAM noi voi con tro la R0
; hay R1
MOV A,#24h
MOV 20h,#53h
MOV R0,#20h
XCHD A,@R0 ; A = 23h va (20h) = 54h
Các TD minh họa tập lệnh 8051 – trang 5