Đ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
NUM2M EQU 20h ; Địa chỉ ở IRAM (RAM nội) có trị số bằng NUM2
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 CMSB = 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
Trang 2; 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
;(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 0 ; 1 cach khac de co R0 <- R0 + 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
CJNE R7, #0FFH, SKIP ; Neu tran duoi thành FF thì phai muon
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_2M EQU 20h ; Dia chi o IRAM co tri so bang BCD1_2
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
Trang 3; Thu lenh ADD voi toan hang BCD 2 digit ( toan hang thu 2 la thanh ghi B)
; Thu lenh ADD voi toan hang BCD 2 digit ( toan hang thu 2 la thanh ghi da dung Rn)
; Thu lenh ADD voi toan hang thu 2 la so BCD 2 digit trong bo nho noi
MOV BCD1_2M,#BCD1_2
ADD A,BCD1_2M ; A <- A + (BCD1_2M) = 25H + 17H = 3CH
; Thu lenh ADD voi toan hang thu 2 la 1 byte trong bo nho noi co pointer la R0
MOV R0,#BCD1_2
; 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
; 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
Trang 4; 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
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
; Thu lenh RL A
MOV A,#NUM1 ; A = 0000_1111B = 0FH = 15
RL A ; A = 0011_1100B = 3CH = 60 = 30 x 2 = 15 x 22
; Xoay phai voi co C
MOV A,#NUM1 ; A = 0000_1111B = 15
RRC A ; A = 1000_0111B = 87H va C = 1
; Xoay trai voi co C
MOV A,#NUM1 ; A = 0000_1111B = 15
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
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
Trang 5; 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
; Thử lệnh SWAP
MOV A,#47H
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
; Đ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
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
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
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
PUSH 07
PUSH 01
; 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
Trang 6sjmp $
END
TD : Minh họa các lệnh chuyển dữ liệu: MOVC
; TD: mov02.asm
; Đọc liên tục dữ liệu X từ P0 và xuất ra P1 giá tri X2
; Xuất dạng BCD 4 digit ở P2 (2 digit cao) va P3 (2 digit thap)
MOV P0,#0FFH ; Đặt cấu hình cho P0 là INPUT
MOV DPTR,#X2_BCD
ANL A,#0FH ; Bảo đảm chỉ tính tối đa là 15^2 = 225
PUSH ACC ; Lưu trữ cho lần gọi sau
CALL SQUARE ; Assembler tự đổi sang ACALL hay LCALL
MOV P1,A
POP ACC
CALL SQ_BCD
SJMP L1
; Chương trình con tính X^2 bằng cách tra bảng với thanh ghi nền là PC
SQUARE:
INC A ; Điều chỉnh để lấy số liệu đúng!!
MOVC A,@A+PC
RET
TABLE_X2: DB 0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225 ; X^2
; Chương trình con tra kết quả X^2 với biểu diễn BCD 4 digit
; Tra bảng bằng thanh ghi nền DPTR
SQ_BCD:
CLR C
RL A ; A < 2 x A vì mỗi phần tử của bảng dài 2 byte
PUSH ACC
MOVC A,@A+DPTR
MOV P2,A ; Xuat 2 ky so BCD cao
POP ACC
INC A
MOVC A,@A+DPTR
MOV P3,A ; Xuat 2 ky so BCD thap
RET
X2_BCD:
DW 0000H, 0001H, 0004H, 0009H, 0016H, 0025H, 0036H, 0049H, 0064H, 0081H; 02 -> 92
DW 0100H, 0121H, 0144H, 0169H, 0196H, 0225H; 102 -> 152
END
TD : Minh họa các lệnh với biến Boole (toán hạng 1 bit)
;TD: boole01.asm
; Thuc hien cac phep toan boole co ban NOT, AND, OR, XOR, NAND, va NOR
F1 EQU PSW.1 ; Dùng thêm bit này làm biến tạm (đã có F0)
MOV P1,#03H; Dat cau hinh P1.0 va P1.1 lam INPUT
LOOP: MOV C,X
MOV C,Y
MOV C,F0
MOV C,F0
Trang 7MOV XANDY,C ; X AND Y
MOV XNANDY,C; X NAND Y
MOV C,F0
JNB X,SKIP ; Neu X=0 thi X XOR Y = Y
SKIP: SJMP LOOP ; Phải có lặp lại, nếu không sẽ không thể hiện được cổng logic!!
END
TD : Minh họa các phép toán logic với biến Boole (toán hạng 1 bit)
;TD: boole02.asm
; Định trị hàm Boole: F = (XY'+ WZ)(XZ'W' + X'Z)= tích của 2 tổng Boole
; Giả sử các biến X, Y, Z, W được đọc vào từ P1.0 P1.3 và biến ra F để ở P1.7
LOOP: MOV C,X
; xet tong thu 2
MOV C,W
SJMP LOOP
SJMP LOOP
SJMP LOOP
END
TD : Minh họa các lệnh nhảy theo trị biến Boole: JB, JNB
;TD: boole03.asm
; Mô phỏng mạch đếm lên (đếm 10): ngõ ra nhị phân ở 4 bit thấp P2, giả sử được nối với mạch hiển thị số
; BCD và xung nhịp CK (kích cạnh xuống) được nối với chân P3.7
LOOP: JNB CK,$ ; đợi CK có mức 1
JB CK,$ ; đợi CK có mức 0 ==> phát hiện được cạnh xuống
CJNE R0,#10,NEXT
MOV R0,#0
SJMP LOOP
END
Trang 8; SV có thể dùng Proteus để thấy rõ hơn hoạt động counter này
TD : Minh họa các lệnh rẽ nhánh chương không điều kiện: JMP
; TD: branch01.asm
; Chuong trinh doc lien tuc gia tri tu P0 (gia su < 4)
; Nếu P0=0 thì xử lý theo CASE_0, = 1 theo CASE_1,
MOV DPTR,#JMP_TABLE
ANL A,#03H ; Bao dam cho gia tri chon < 4 ! , sau lenh nay C =0
JMP @A+DPTR
JMP_TABLE:
AJMP CASE_0 ; lenh nay 2 byte
AJMP CASE_1
AJMP CASE_2
; Day la doan phuc vu cho CASE_3
; chia P1 cho P2 va xuat thuong so o 4 bit cao cua P3 va du so o 4 bit thap cua P3
; gia su thuong so va du so <= 15
CALL DIV_P1P2
JMP L1
CASE_0: ; Tinh tong cua P1 va P2, ket qua xuat ra P3
MOV A,P1
ADD A,P2
MOV P3,A
JMP L1
CASE_1: ; Tinh hieu cua P1 va P2, ket qua xuat ra P3
MOV A,P1
CLR C
SUBB A,P2
MOV P3,A
JMP L1
CASE_2: ; Tinh nhan cua P1 va P2, ket qua xuat ra P3
MOV A,P1
MOV B,P2
MUL AB ; gia su ket qua <= 255
MOV P3,A
JMP L1
; Thuc hien P1/P2
DIV_P1P2:
MOV A,P1
MOV B,P2
DIV AB
SWAP A
ORL A,B
MOV P3,A
RET
END
TD : Minh họa các lệnh rẽ nhánh chương trình theo điều kiện: JZ, JNZ, DJNZ, va CJNE
; TD: branch02.asm
MOV P0,#0FFH
MOV A,P0
JZ ZERO
JMP NEXT
ZERO: MOV P1,#0FH
NEXT:
; Đoạn chương trình đếm các phần tử bằng 0 trong 1 bảng ở RAM ngoài (địa chỉ đầu là
; 0000H) với byte đầu là số phần tử trong bảng
; Nếu bảng có dải trị số: 07h 02h 00h 03h 05h 00h 09h 0Ch
; thì kết quả thanh ghi B = 2
MOV DPTR,#0
Trang 9MOVX A,@DPTR
MOV R0, A ; So phan tu cua bang dat trong R0
MOV B,#0
MOVX A,@DPTR
JNZ SKIP
INC B
SKIP: DJNZ R0,L1
; Đếm tổng số các phần tử có trị >=3, kết quả cất vào R1, với TD này cho R1 = 3
MOV DPTR,#0
MOVX A,@DPTR
MOV R0, A ; So phan tu cua bang dat trong R0
MOV R1,#0
MOVX A,@DPTR
CJNE A,#5,CHECK
CHECK:
JC CONT
; C = 0 co nghia la A >= 5
INC R1
CONT: DJNZ R0, L2
SJMP $
END
TD : Mô phỏng mạch so sánh 2 số nhị phân 4 bit X và Y (X = P1.7 P1.4, Y = P1.3 P1.0),
mạch co 3 ngõ ra P2.0 = 1 nếu X < Y, P2.1 = 1 nếu X = Y, và P2.2 = 1 nếu X > Y
; TD: branch03.asm
LOOP: MOV A,P1 ; A = X:Y (A do 2 số 4 bit X va Y hợp lại)
CJNE A, B, XNEY ; so sanh X voi Y muc dich se dat cac co
XEQY: ; truong hop X = Y
SJMP LOOP
XLTY: ; truong hop X < Y
SJMP LOOP
XGTY: ; truong hop X > Y
SJMP LOOP
END