Giáo trình Vi điều khiển 8051 Assembly - Chương 6: Các lệnh số học và các chương trình

Trong 8051 để cộng các số với nhau thì thanh ghi tổng (A) phải được dùng

đến. Dạng lệnh ADD là:

ADD A, nguồn; A = A + nguồn

Lệnh ADD được dùng để cộng hai toán hạng. Toán hạng đích luôn là thanh

ghi A trong khi đó toán hạng nguồn có thể là một thanh ghi dữ liệu trực tiếp hoặc là

ở trong bộ nhớ. Hãy nhớ rằng các phép toán số học từ bộ nhớ đến bộ nhớ không bao

giờ được phép trong hợp ngữ. Lệnh này có thể thay đổi một trong các bit AF, CF

hoặc PF của thanh ghi cờ phụ thuộc vào các toán hạng liên quan.

pdf11 trang | Chuyên mục: Kiến Trúc Máy Tính | Chia sẻ: dkS00TYs | Lượt xem: 7526 | Lượt tải: 2download
Tóm tắt nội dung Giáo trình Vi điều khiển 8051 Assembly - Chương 6: Các lệnh số học và các chương trình, để xem tài liệu hoàn chỉnh bạn click vào nút "TẢI VỀ" ở trên
 điều khiển chỉ hỗ trợ phép nhân byte với byte. Các byte được giả thiết là 
dữ liệu không dấu. Cấu trúc lệnh như sau: 
 MOV AB ; Là phép nhân A ´ B và kết quả 16 bit được đặt trong A và B. 
 Khi nhận byte với byte thì một trong các toán hạng phải trong thanh ghi A và 
toán hạng thứ hai phải ở trong thanh ghi B. Sau khi nhân kết quả ở trong các thanh 
ghi A và B. Phần tiếp thấp ở trong A, còn phần cao ở trong B. Ví dụ dưới đây trình 
bày phép nhân 25H với 65H. Kết quả là dữ liệu 16 bit được đặt trong A và B. 
 MOV A, #25H ; Nạp vào A giá trị 25H 
 MOV B, 65H ; Nạp vào B giá trị 65H 
 MUL AB ; 25H*65H = E99 với B = 0EH và A = 99H 
 Bảng 6.1: Tóm tắt phép nhân hai số không dấu (MULAB) 
Nhân Toán hạng 1 Toán hạng 2 Kết quả 
Byte*Byte A B A = byte thấp, B = byte cao 
6.2.2 Chia hai số không dấu. 
 8051 cùng chỉ hỗ trợ phép chia hai số không dấu byte cho byte với cú pháp: 
 DIV AB ; Chia A cho B 
 Khi chia một byte cho một byte thì tử số (số bị chia) phải ở trong thanh ghi A 
và mẫu số (số chia) phải ở trong thanh ghi B. Sau khi lệnh chia DIV được thực hiện 
thì thương số được đặt trong A, còn số dư được đặt trong B. Xét ví dụ dưới đây: 
 MOV A, #95 ; Nạp số bị chia vào A = 95 
 MOV B, #10 ; Nạp số chia vào B = 10 
 DIV AB ; A = 09 (thương số); B = 05 (số dư) 
 Lưu ý các điểm sau khi thực hiện “DIV AB” 
Lệnh này luôn bắt CY = 0 và OV = 0 nếu tử số không phải là số 0 
Nếu tử số là số 0 (B = 0) thì OV =1 báo lỗi và CY = 0. Thực tế chuẩn trong tất 
cả mọi bộ vi xử lý khi chia một số cho 0 là bằng cách nào đó báo có kết quả không 
xác định. Trong 8051 thì cờ OV được thiết lập lên 1. 
 Bảng 6.2: Tóm tắt phép chia không dấu (DIV AB). 
Phép chia Tử số Mẫu số Thương số Số dư 
Byte cho Byte A B A B 
6.2.3 Một ứng dụng cho các lệnh chia. 
 Có những thời điểm khi một bộ ADC được nối tới một cổng và ADC biểu 
diễn một số dư nhiệt độ hay áp suất. Bộ ADC cấp dữ liệu 8 bit ở dạng Hex trong dải 
00 - FFH. Dữ liệu Hex này phải được chuyển đổi về dạng thập phân. Chúng ta thực 
hiện chia lặp nhiều lần cho 10 và lưu số dư vào như ở ví dụ 6.8. 
Ví dụ 6.8: 
a- Viết một chương trình để nhận dữ liệu dạng Hex trong phạm vi 00 - FFH từ cổng 
1 và chuyển đổi nó về dạng thập phân. Lưu các số vào trong các thanh ghi R7, R6 và 
R5 trong đó số có nghĩa nhỏ nhất được cất trong R7. 
b- Phân tích chương trình với giả thiết P1 có giá trị FDH cho dữ liệu. 
Lời giải: 
a) 
 MOV A, #0FFH 
 MOV P1, A ; Tạo P1 là cổng đầu vào 
 MOV A, P1 ; Đọc dữ liệu từ P1 
 MOV B, #10 ; B = 0A Hex (10 thập phân) 
 DIV AB ; Chia cho 10 
 MOV R7, B ; Cất số thấp 
 MOV B, #10 ; 
 DIV AB ; Chia 10 lần nữa 
 MOV R6, B ; Cất số tiếp theo 
 MOV R5, A ; Cất số cuối cùng 
b) Để chuyển đổi số nhị phân hay Hex về số thập phân ta thực hiện chia lặp cho 10 
liên tục cho đến khi thương số nhỏ hơn 10. Sau mỗi lần chia số dư được lưu cất. 
Trong trường hợp một số nhị phân 8 bit như FDH chẳng hạn ta có 253 số thập phân 
như sau (tất cả trong dạng Hex) 
 Thương số Số dư 
FD/0A 19 3 (Số thấp - cuối) 
19/0A 2 5 (Số giữa) 
 2 (Số đầu) 
 Do vậy, ta có FDH = 253. Để hiển thị dữ liệu này thì nó phải được chuyển đổi 
về ASCII mà sẽ được mô tả ở chương sau. 
6.3 Các khái niệm về số có dấu và các phép tính số học. 
 Tất cả mọi dữ liệu từ trước đến giờ đều là các số không dấu, có nghĩa là toàn 
bộ toán hạng 8 bit đều được dùng cho bộ lớn. Có nhiều ứng dụng yêu cầu dữ liệu có 
dấu, phần này sẽ bàn về những lệnh liên quan đến các số có dấu. 
6.3.1 Khái niệm về các số có dấu trong máy tính. 
 Trong cuộc sống hàng ngày các số được dùng có thể là số âm hoặc dương. Ví 
dụ 5 độ dưới 00C được biểu diễn là -50C và 20 độ trên 00C được biểu diễn là +200C. 
Các máy tính cũng phải có khả năng đáp ứng phù hợp với các số ấy. Để làm được 
điều ấy các nhà khoa học máy tính đã phát minh ra sự xắp xếp biểu diễn các số âm 
có dấu và số dương có dấu như sau: Bit cao nhất MSB được để dành cho bit dấu (+) 
hoặc (-), còn các bit còn lại được dùng biểu diễn độ lớn. Dấu được biểu diễn bởi 0 
đối với các số dương và một số đối với các số âm (-). Biểu diễn của một byte có dấu 
được trình bày trên hình 6.2. 
 Hình 6.2: Các toán hạng 8 bit có dấu. 
a- Các toán hạng 8 bit có dấu: Trong các toán hạng A byte có dấu thì bit cao nhất 
MSB là D7 được dùng để biểu diễn dấu, còn 7 bit còn lại từ D6 - D0 dùng để biểu 
diễn độ lớn của số đó. Nếu D7 = 0 thì đó là toán hạng dương và nếu D7 = 1 thì nó là 
toán hạng âm. 
b- Các số dương: Dải của các số dương có thể được biểu diễn theo dạng cho trên 
hình 6.2 là từ 0 đến +127 thì phải sử dụng toán hạng 16 bit. Vì 8051 không hỗ trợ dữ 
liệu 16 bit nên ta không bàn luận đến. 
c- Các số âm: Đối với các số âm thì D7 = 1, tuy nhiên độ lớn được biểu diễn ở dạng 
số bù 2 của nó. Mặc dù hợp ngữ thực hiện việc chuyển đổi song điều quan trọng là 
hiểu việc chuyển đổi diễn ra như thế nào. Để chuyển đổi về dạng biểu diễn số âm 
(bù 2) thì tiến hành theo các bước sau: 
1. Viết độ lớn của số ở dạng nhị phân 8 bit (không dấu). 
2. Đảo ngược tất cả các bit 
3. Cộng 1 vào nó. 
Ví dụ 6.9: Hãy trình bày cách 8051 biểu diễn số - 5. 
 D7 D6 D5 D4 D3 D2 D1 D0 
Sign Magnitu 
Lời giải: 
 Hãy quan sát các bước sau: 
 0000 0101 Biểu diễn số 5 ở dạng 8 bit nhị phân 
 1111 1010 Đảo các bit 
 1111 1011 Cộng (thành số FB ở dạng Hex) 
 Do vậy, số FBH là biểu diễn số có dấu dạng bù 2 của số - 5. 
Ví dụ 6.10: Trình bày cách 8051 biểu diễn - 34H. 
Lời giải: 
 Hãy quan sát các bước sau: 
0011 0200 Số 34 được cho ở dạng nhị phân 
1100 1011 Đảo các bit 
1100 1100 Cộng 1 (thành số CC ở dạng Hex) 
 Vậy số CCH là biểu diễn dạng bù 2 có dấu của - 34H. 
Ví dụ 6.11: Trình bày cách 8051 biểu diễn - 128: 
Lời giải: 
 Quan sát các bước sau: 
1000 0000 Số 128 ở dạng nhị phân 28 bit 
0111 1111 Đảo các bit 
1000 0000 Cộng 1 (trở thành số 80 dạng Hex) 
 Vậy - 128 = 80H là biểu diễn số có dấu dạng bù 2 của - 128. 
 Từ các ví dụ trên đây ta thấy rõ ràng rằng dải của các số âm có dấu 8 bit là - 1 
đến - 128. Dưới đây là liệt kê các số có dấu 8 bit: 
Số thập phân Số nhị phân Số Hex 
-128 1000 0000 80 
-127 1000 0001 81 
-126 1000 0010 82 
... ................. ... 
-2 1111 1110 FE 
-1 1111 1111 FF 
0 0000 0000 00 
+1 0000 0001 01 
+2 0000 0010 02 
... .................. ... 
-127 0111 1111 FE 
6.3.2 Vấn đề tràn trong các phép toán với số có dấu. 
 Khi sử dụng các số có dấu xuất hiện một vấn đề rất nghiêm trọng mà phải 
được sử lý. Đó là vấn đề tràn, 8051 báo có lỗi bằng cách thiết lập cờ tràn OV nhưng 
trách nhiệm của lập trình viên là phải cẩn thận với kết quả sai. CPU chỉ hiểu 0 và 1 
và nó làm ngơ với việc chuyển đổi số âm, số dương của con người. Vậy tràn số là gì? 
Nếu kết quả của một phép toán trên các số có dấu mà quá lớn đối với thanh ghi thì 
xuất hiện sự tràn số và lập trình viên phải được cảnh báo. Xét ví dụ 6.12 dưới đây. 
Ví dụ 6.12: 
 Khảo sát đoạn mã sau và phân tích kết quả. 
 MOV A, # + 96 ; A = 0110 0000 (A = 60H) 
 MOV R1, # + 70 ; R1 = 0100 0110 (R1 = 46H) 
 ADD A, R1 ; A = 1010 0110 = A6H = - 90 
 Sai !!! 
Lời giải: 
 + 96 0110 0000 
 + + 70 0100 0110 
 - 166 1010 0110 và OV = 1 
 Theo CPU kết quả là -90 và đó là kết quả sai nên CPU bật cờ OV = 1 để báo 
tràn số. 
 Trong ví dụ 6.12 thì + 96 được cộng với + 70 và kết quả theo CPU là - 90. Tại 
sao vậy? Lý do là kết quả của + 96 + 70 = 172 lớn hơn số mà thanh ghi A có thể 
chứa được. Cũng như tất cả mọi thanh ghi 8 bit khác, thanh ghi A chỉ chứa được đến 
số + 127. Các nhà thiết kế của PCU tạo ra cờ tràn OV phục vụ riêng cho mục đích 
báo cho lập trình viên rằng kết quả của phép toán số có dấu là sai. 
6.3.3 Khi nào thì cờ tràn OV được thiết lập? 
 Trong các phép toán với số có dấu 8 bit thì cờ OV được bật lên 1 khi xuất 
hiện một trong hai điều kiện sau: 
1. Cờ nhớ từ D6 sang D7 nhưng không có nhớ ra từ D7 (cờ CY = 0) 
2. Có nhớ ra từ D7 (cờ CY = 1) nhưng không có nhớ từ D6 sang D7 
 Hay nói cách khác là cờ tràn OV được bật lên 1 nếu có nhớ từ D6 sang D7 
hoặc từ D7 nhưng không đồng thời xảy ra cả hai. Điều này có nghĩa là nếu có nhớ cả 
từ D6 sang D7 và từ D7 ra thì cờ OV = 0. Trong ví dụ 6.12 vì chỉ có nhớ từ D7 ra nên 
cờ OV = 1. Trong ví dụ 6.13, ví dụ 6.14 và 6.15 có minh hoạ thêm về sử dụng cờ 
tràn trong các phép số học với số có dấu. 
Ví dụ 6.13: 
 Hãy quan sát đoạn mã sau để ý đến vai trò của cờ OV. 
 MOV A, # -128 ; A = 1000 0000 (A= 80H) 
 MOV R4, # -2 ; R4 = 1111 (R4 = FEH) 
 ADD A, R4 ; A = 0111 1110 (A = 7EH = +126, invalid) 
Lời giải: 
 - 128 1000 0000 
 + - 2 1111 1110 
 -130 0111 1110 và OV = 1 
 Theo CPU thì kết quả + 126 là kết quả sai, nên cờ OV = 1. 
Ví dụ 6.14: 
 Hãy quan sát đoạn mã sau và lưu ý cờ OV. 
 MOV A, # -2 ; A = 1111 1110 (A = FEH) 
 MOV R1, # -5 ; R1 = 1111 1011 (R1 = FBH) 
 ADD A, R1 ; A = 1111 1001 (A = F9H = -7, correct, OV = 0) 
Lời giải: 
 - 2 1111 1110 
 + - 5 1111 1011 
 - 7 1111 1001 và OV = 0 
 Theo CPU thì kết quả - 7 là đúng nên cờ OV = 0. 
Ví dụ 6.15: 
 Theo dõi đoạn mã sau, chú ý vai trò của cờ OV. 
 MOV A, # +7 ; A = 0000 0111 (A = 07H) 
 MOV R1, # +18 ; R1 = 0001 0010 (R1 = 12H) 
 ADD A, R1 ; A = 1111 1001 (A = 19H = -25, correct, OV = 0) 
Lời giải: 
 7 0000 0111 
 - 18 0001 0010 
 25 0001 1001 và OV = 0 
 Theo CPU thì kết quả - 25 là đúng nên cờ OV = 0. 
 Từ các ví dụ trên đây ta có thể kết luận rằng trọng bất kỳ phép cộng số có dấu 
nào, cờ OV đều báo kết quả là đúng hay sai. Nếu cờ OV = 1 thì kết quả là sai, còn 
nếu OV = 0 thì kết quả là đúng. Chúng ta có thể nhấn mạnh rằng, trong phép cộng 
các số không dấu ta phải hiển thị trạng thái của cờ CY (cờ nhớ) và trong phép cộng 
các số có dấu thì cờ tràn OV phải được theo dõi bởi lập trình viên. Trong 8051 thì 
các lệnh như JNC và JC cho phép chương trình rẽ nhánh ngay sau phép cộng các số 
không dấu như ở phần 6.1. Đối với cờ tràn OV thì không có như vậy. Tuy nhiên, 
điều này có thể đạt được bằng lệnh “JB PSW.2” hoặc “JNB PSW.2” vì PSW thanh 
ghi cờ có thể đánh địa chỉ theo bit. 

File đính kèm:

  • pdfVi_dieu_khien_8051_ Assembly_06_LenhSohocVaChuongTrinh.pdf
Tài liệu liên quan