Chapter3 LapTrinh Assembly PIC18 V2q tài liệu, giáo án, bài giảng , luận văn, luận án, đồ án, bài tập lớn về tất cả các...
Trang 1CHƯƠNG 3: LẬP TRÌNH HỢP NGỮ CHO PIC18
Mục tiêu của chương này sẽ giúp người đọc có khả năng: giải thích được cấu trúc của một chương trình hợp ngữ; biết sử dụng các chỉ dẫn hợp dịch để chỉ định các khối bộ nhớ và khai báo các hằng số; có thể viết các chương trình hợp ngữ cho các phép toán số học và các vòng lặp chương trình; có khả năng viết chương trình tạo các khoản thời gian trễ cần thiết
Một chương trình được viết bằng hợp ngữ bao gồm chuỗi các phát biểu, chương trình hợp ngữ cho PIC18 gồm có 3 loại phát biểu:
Chỉ dẫn hợp dịch: là các lệnh hợp dịch mà nó sử dụng để điều khiển hợp dịch là các ngõ vào, ngõ ra và dữ liệu Một chương trình hợp ngữ bất kỳ phải được kết thúc bằng chỉ
dẫn END Khi gặp chỉ dẫn END thì chương trình sẽ kết thúc
Các lệnh hợp ngữ: các lệnh này là các lệnh của PIC18, một vài lệnh được định nghĩa với các nhãn PIC18 cho phép sử dụng đến 77 lệnh khác nhau
Các chú thích: có hai loại chú thích trong hợp ngữ Loại đầu tiên được sử dụng để giải thích chức năng của một lệnh đơn giản hay chỉ dẫn đơn giản Loại thứ hai giải thích chức năng của một nhóm các lệnh hoặc các chỉ dẫn hay hoặc toàn bộ thủ tục
Mã nguồn của trình hợp ngữ có thể được viết bằng cách sử dụng bất kỳ trình soạn thảo
tập văn bản ASCII Mỗi dòng của tập mã nguồn có thể chứa đựng lên tới 4 vùng: nhãn (label), lệnh gợi nhớ (mnemonic), toán hạng (operand), chú thích (comment) Trật tự các vùng này
phải theo đúng trật tự Các nhãn phải ở cột thứ nhất, vùng gợi nhớ phải bắt đầu ở cột thứ hai hoặc hơn, kế tiếp là các toán hạng Các ghi chú có thể ở sau các toán hạng, lệnh gợi nhớ hay nhãn và nó có thể bắt đầu ở bất kỳ cột nào Độ rộng cột trong trình hợp ngữ cho phép tối đa
Ví dụ 3.1: các lệnh sau chứa các nhãn đúng:
(a) Loop addwf 0x20,F,A
(b) _khoa addlw 0x03
Trang 2(c) Hb?gt andlw 0x7F
(d) thuc_hien bsf 0x07, 0x05,A
Ví dụ 3.2: các lệnh sau chứa các nhãn không đúng quy định:
(a) label_1 btfsc 0x15, 0x07,B ; Nhãn bắt đầu ở cột thứ 2
(a) False equ 0 ; equ là chi dẫn hợp dịch
(b) goto start ; goto là lệnh gợi nhớ
(c) Loop: incf 0x20,W,A ; incf là lệnh gợi nhớ
Vùng toán hạng
Nếu có một toán hạng hiện diện thì nó phải ở sau lệnh gợi nhớ Vùng toán hạng có thể
có nhiều toán hạng cho các lệnh hay các đối số cho các chỉ dẫn hợp dịch
Ví dụ 3.4: các dạng toán hạng
(c) movff 0x20,0x80 ; “0x20” và “0x80” là các toán hạng
Vùng chú thích
Vùng chú thích được thêm vào (không bắt buộc phải có) để giải thích cho dễ nhớ và dễ hiểu
Ví dụ 3.5: cách ghi chú thích trong chương trình
(b) ; Bắt đầu chương trình con
Lưu ý: nếu bằng tiếng Việt thì không có dấu, trong các chú thích trên sử dụng tiếng Việt nhằm để dễ đọc
3.2 CÁC CHỈ DẪN HỢP DỊCH
Các chỉ dẫn hợp dịch trông giống như các lệnh trong trình hợp ngữ Hầu hết các chỉ dẫn hợp dịch thông báo cho trình hợp dịch để làm gì đó khác hơn việc tạo ra mã máy cho một lệnh Các chỉ dẫn hợp dịch cung cấp cho người lập trình hợp ngữ ý nghĩa là để chỉ thị cho hợp ngữ cách thức để xử lý các lệnh hợp ngữ xảy ra sau Các chỉ dẫn cũng cho phép định nghĩa các hằng số và không gian dự trữ cho các biến thay đổi
Trình MPASM cung cấp 5 loại chỉ dẫn: chỉ dẫn điều khiển, chỉ dẫn dữ liệu, chỉ dẫn thống kê, chỉ dẫn macro và chỉ dẫn đối tượng
Trang 3Chỉ rõ cơ số mặc định Huỷ nhãn thay thế Thực hiện vòng while khi điều kiện là đúng
[<name>] code [<address>]
#define <name> [<value>]
#define <name> [<arg>, …,
<arg>] <value>
else end endif endw
movlw 0x1a movlw io_2,A endif
[<label>] code [<ROM address>]
Đây là chỉ dẫn tuyên bố bắt đầu của một phần mã chương trình Nếu nhãn không được
chỉ rõ thì phần này ẩn có tên là “.code”
reset code 0x00 ; khởi tạo bộ nhớ chương trình bắt đầu = 0
goto start ; thực hiện nhảy đến nhãn start
#define <name> [<string>]
Chỉ dẫn này định nghĩa một chuỗi thay thế Bất kể khi <name> được thấy trong mã hợp ngữ thì <string> sẽ được thay thế
#define length 20
#define config 0x17,7,A
#define sum3(x,y,z) (x + y + z)
Trang 4
test dw sum3(1, length, 200) ; đặt (1+20+200) ở vị trí này
bsf config ; đặt bit 7 của thanh ghi dữ liệu 0x17 bằng 1
#include “<include_file>”
Chỉ dẫn này chứa đựng tập tin nguồn, các tập tin nguồn như p18F8720.inc, p18F452.inc, p18F4550, Các tập tin này đã định nghĩa và khai báo sẵn về phần cứng của VĐK Mục đích của chỉ dẫn này là để khai báo VĐK cụ thể sử dụng trong thiết kế
#include “p18F8720.inc”
#include “p18F452.inc”
radix <default_radix>
Chỉ dẫn này để đặt cơ số mặc định cho các biểu thức dữ liệu Cơ số mặc định là hex
Các giá trị cơ số đúng: hex (thập lục), dee (thập phân), oct (bát phân)
while <expr>
endw
Trang 5Các dòng ở giữa while và endw được hợp dịch với độ dài <expr> được ước lượng là đúng Vòng lặp while có thể chứa đựng nhiều nhất là 100 dòng và được lặp lại tối đa là 256
Tạo dữ liệu bằng số và text
Khai báo dữ liệu kích thước 1 byte
Định nghĩa bảng Khai báo dữ liệu kích thước 1 word
Kết thúc một khối hằng tự động Định nghĩa hằng số
Điền bộ nhớ Đặt trước bộ nhớ Định nghĩa biến Khai báo biến biểu tượng
cblock [<expr>]
const [<label> = <value>], …, [<label> =
<expr>]
[<label>] da <expr>[, <expr>, …, <expr>]
[<label>] data <expr>[, <expr>, …, <expr>]
[<label>] data <text string>[, < text string >, …] [<label>] db <expr>[, <expr>, …, <expr>]
[<label>] db <text string>[, < text string >, …] [<label>] dt <expr>[, <expr>, …, <expr>]
[<label>] dt <text_string>[, < text_string >, …] [<label>] dw <expr>[, <expr>, …, <expr>]
[<label>] dw <text_string>[, < text_string >, …]
endc
<label> equ <expr>
[<label>] fill <expr>, <count>
[<label>] res <mem_units>
<label> set <expr>
variable <label> [= <expr>][, <label> [=
<expr>] …]
Bảng 3.3: chỉ rõ cơ số trong MPASM
Thập phân Thập lục
Trang 6Bát phân Nhị phân ASCII
Chỉ dẫn cblock định nghĩa một danh sách các hằng số đã đặt tên, mỗi nhãn chỉ định giá
trị là 1 hoặc lớn hơn giá trị của nhãn trước Mục đích của chỉ dẫn này để ấn định các khoản địa chỉ cho nhiều nhãn
<expr> chỉ giá trị bắt đầu cho tên đầu tiên trong khối Nếu cblock đầu tiên trong tập mã nguồn không có <expr> sẽ ấn định các giá trị bắt đầu bằng 0
Nếu <increment> được chỉ rõ, khi đó nhãn kế tiếp được ấn định giá trị của <độ tăng>
Các giá trị đã ấn định cho các ký hiệu trong khối thứ hai:
const <label> = <expr> [ , <label> = <expr>]
Chỉ dẫn này tạo ra các ký hiệu sử dụng trong các biểu thức MPASM Ví dụ:
const chu_ky = D’50’
sẽ lấy giá trị 50 sử dụng bất kỳ khi nào ký hiệu chu_ky được gọi tới
[<label>] data <expr>[,<expr>, ,<expr>]
[<label>] data “<text_string>”[,“<text_string>”]
Trang 7Chỉ dẫn data cũng có thể được viết là da Chỉ dẫn này để khởi tạo 1 word hoặc nhiều hơn cho dữ liệu bộ nhớ chương trình Mỗi <expr> được lưu trữ với độ dài 1 word Các ví dụ
sau minh hoạ cách sử dụng các chỉ dẫn này:
data 1,2,3 ; các hằng số
data “count from 1,2,3” ; chuỗi text
data main ; nhãn xác định lại đúng vị trí
[<label >] db < expr >[,< expr >, ,< expr >]
Chỉ dẫn này để giành các word bộ nhớ chương trình với các giá trị có độ rộng 8 bit Khi
có nhiều biểu thức sẽ liên tục điền các byte liên tiếp cho đến khi kết thúc của các biểu thức
db ‘b’,0x22, ‘t’,0x1f, ‘s’,0x30
[<label>] de <expr>[,< expr >, ,< expr >]
Chỉ dẫn này để dự trữ các word bộ nhớ với dữ liệu 8 bit Mỗi <expr> phải được ước lượng thành giá trị 8 bit 8 bit cao của 1 word là bằng 0 Mỗi ký tự trong một chuỗi được lưu trữ bằng 1 word riêng biệt Mặc dù được thiết kế để khởi tạo dữ liệu EEPROM trên PIC16C8X, nhưng chỉ dẫn này có thể sử dụng cho bất kỳ vị trí nào của tất các bộ xử lý org 0x2000
de “this is my program”, 0 ; 0 xác định vị trí
[<label >] dt < expr >[, < expr >, ,< expr >]
Đây là chỉ dẫn phát ra chuỗi các lệnh retlw, một lệnh ứng với mỗi <expr> Mỗi <expr> phải mang giá trị 8 bit Mỗi ký tự trong chuỗi được lưu trữ trong lệnh retlw riêng của nó
dt “A new era i comming”, 0
dt 1,2,3,4
[<label >] dw < expr >[, < expr >, ,< expr >]
Chỉ dẫn này để dự trữ các word bộ nhớ chương trình đối với dữ liệu, sự khởi tạo không gian đó để chỉ rõ các giá trị Các giá trị này được lưu trữ trong các vị trí bộ nhớ liên tiếp và vị trí được gia tăng bởi 1
dw 39, 24, “display data”
dw array_cnt-1
< label > equ < expr >
Chỉ dẫn equ để định nghĩa một hằng số Khi nhãn xuất hiện chỗ nào trong chương trình,
trình hợp dịch sẽ thay thế nó bằng <expr>
true equ 1
false equ 0
four equ 4
Trang 8[<label >] fill < expr >, <count>
Chỉ dẫn này chỉ rõ giá trị điền vào bộ nhớ Giá trị để điền vào là <expr>, trong khi đó
số các word mà giá trị được lập lại được biểu diễn là <count>
fill 0x2020, 5 ; điền 5 word có giá trị 0x2020 vào bộ nhớ chương trình
[<label >] res <mem_units>
MPASM sử dụng một con trỏ chỉ vị trí bộ nhớ để lưu giữ địa chỉ cho vị trí bộ nhớ kế tiếp Chỉ dẫn này thông báo vị trí hiện hành trong <mem_units> cho con trỏ
buffer res 64
<label> set <expr>
Trong chỉ dẫn này, <label> được ấn định giá trị cho biểu thức được chỉ thị bằng <expr>
Chỉ dẫn set tương đương chức năng chỉ dẫn equ ngoại trừ giá trị được thay đổi tuần tự bằng chỉ dẫn set khác
area_hi set 0x22
area_lo set 0x23
variable <label> [= <expr>][,<label> [=<expr>] ]
Chỉ dẫn này sẽ tạo ra các ký hiệu sử dụng trong các biểu thức MPASM Các biến và các hằng có thể được sử dụng thay thế cho nhau trong biểu thức Chỉ dẫn variable tạo ra một ký hiệu mà nó tương đương chức năng được tạo bởi chỉ dẫn set Khác nhau là chỉ dẫn variable không yêu cầu các ký tự đó được khởi tạo khi chúng được công nhận
3.2.3 Các chỉ dẫn macro
Macro là tên được gán cho một hay nhiều hơn những phát biểu hợp ngữ Trong chương trình hợp ngữ mà có một đoạn chương trình được gặp nhiều lần tại nhiều chỗ, để tránh viết nhiều lần thì ta đặt tên cho đoạn chương trình này Sau đó muốn thực hiện lại đoạn chương trình này ta chỉ việc gọi tên chương trình này, chương trình này được gọi là chương trình macro
Cấu trúc của chương trình macro:
<label> macro [<arg>, , <arg>]
Khai báo định nghĩa macro
Mở rộng macro Khai báo biến macro địa phương Tắt mở rộng macro
endm exitm
[<label>] macro [<arg>, …, <arg>]
expand local <label> [, <label>]
noexpand
Để cầu khẩn macro, phải chỉ rõ tên và các đối số của macro, và trình hợp dịch sẽ chèn
chuỗi lệnh giữa các chỉ dẫn macro và endm vào đoạn chương trình của chúng ta
Trang 9Local <label>[, <label> ]
Chỉ dẫn này công nhận các yếu tố dữ liệu được chỉ rõ sẽ chỉ có ảnh hưởng trong cục bộ
(local) đối với macro
<main code segment>
abc macro width
local len, label ; len và label có tác dụng cục bộ
len set width ; điều chỉnh biến len cục bộ
label res len ; dự trữ buffer
len set len-10
Trang 10kê Chèn các dòng thống kê trống Định tiêu đề phụ chương trình Định tiêu đề chương trình
nolist page space <expr>
subtitle “<sub_text>”
title “<title_text>”
error “<text_string>”
Chỉ dẫn này để in ra thông báo lỗi <text_string> Thông báo lỗi sẽ xuất ra tập tin liệt
kê Độ dài của <text_string> từ 1 đến 80 ký tự
errorlevel {0|1|2 +<msgnum> | -<msgnum>}[, ]
Chỉ dẫn này đặt các kiểu các thông báo mà được in ra trong tập tin thống kê và tập tin thông báo lỗi Ý nghĩa các thông số xem trong bảng 3.6
Bảng 3.6: ý nghĩa các thông số của chỉ dẫn ERRORLEVEL
0
1
2 -<msgnum>
+< msgnum>
Các thông báo, cảnh báo và lỗi được in Các cảnh báo và lỗi được in
Các lỗi được in Cấm in thông báo <msgnum>
Cho phép in thông báo <msgnum>
Ví dụ,
errorlevel 1, -202
cho phép các cảnh báo và lỗi được in ra và ngăn cấm in thông báo số 202
list [<list_option>, , <list_option>]
nolist
Chỉ dẫn list có ảnh hưởng để mở ngõ ra thống kê nếu trước đó bị tắt Chỉ dẫn này cũng
có thể cung cấp các lựa chọn trong bẳng 3.7 để điều khiển xử lý hợp ngữ hay định dạng tập
tin thống kê Chỉ dẫn nolist đơn giản để tắt ngõ ra tập tin thống kê
ON
60 None Hex
ON OFF
0
ON
Đặt số số khoảng trắng nhảy Định độ rộng cột
Định ngõ ra tập tin dạng hex, <format> có thể là INHX32, INHX8M hay INHX8S
Sử dụng cú pháp có định dạng tự do Dùng trang định dạng cố định
In bản đồ bộ nhớ trong tập tin thống kê Định số dòng trong một trang
Định kiểu bộ xử lý Ví dụ như PIC18F4550 Đặt cơ số mặc định như hex, dec, oct
In bảng ký hiệu trong tập tin thống kê Cắt xén bớt số dòng thống kê
Đặt mức độ thông báo (xem ERRORLEVEL)
Mở hoặc tắt mở rộng macro
Trang 11Chỉ dẫn này để thiết lập một dòng tiêu đề chương trình thứ hai để sử dụng như một tiêu
đề phụ trong ngõ ra tập thống kê <sub_text> là chuỗi ASCII, tối đa chứa 60 ký tự
3.2.5 Các chỉ dẫn tập tin đối tượng
Có nhiều chỉ dẫn MPASM được sử dụng chỉ để điều khiển để phát ra mã đối tượng Một tập con của các chỉ dẫn này được liệt kê trong bảng 3.8
Bảng 3.8: các chỉ dẫn tập tin đối tượng
Bắt đầu đoạn dữ liệu chưa được khởi tạo được phân chia
banksel <label>
[<name>] code [<address>]
_config <expr> hoặc _config <addr>, <expr>
extern <label> [, <label>]
global <label> [, <label>]
[<name>] idata [<address>]
<label> org <expr>
Processor <processor_type>
[<name>] udata [<address>]
[<name>] udata_shr [<address>]
Trang 12[<label>] code [<ROM address>]
Đây là chỉ dẫn để tuyên bố bắt đầu một đoạn mã chương trình Nếu không có <label>
thì đoạn này có tên là “.code” Địa chỉ bắt đầu được khởi tạo đối với địa chỉ cụ thể hoặc sẽ
được ấn định tại thời điểm xét nếu không có địa chỉ được chỉ rõ
reset code 0x00
goto start
_config <expr> hoặc
_config <addr>, <expr>
Chỉ dẫn này để đặt các bit cấu hình của bộ xử lý đối giá trị được mô tả bởi <expr>
Trước khi chỉ dẫn này, bộ xử lý phải được công bố thông qua chỉ dẫn processor hay list Định dạng ngõ ra tập tin hex phải được đặt thành INHX32 với chỉ dẫn list khi chỉ dẫn này được sử
dụng với họ PIC18
list p = 18F8720, f = INHX32
extern <label> [,<label>, ]
Chỉ dẫn này tuyên bố tên các ký hiệu mà được sử dụng trong khối hiện hành nhưng được xác định như tính toàn cục trong khối khác
extern function_x
call function_x
global <label> [, <label>, ]
Chỉ thị này công nhận các tên ký hiệu mà được định nghĩa trong khối hiện hành và vẫn
có giá trị ảnh huởg trong khối khác Ví dụ,
Global ax, bx
hai biến ax và bx sẽ ảnh hưởng toàn cục
[<label>] idata [<RAM address>]
Chỉ dẫn này để tuyên bố sự bắt đầu của đoạn dữ liệu được khởi tạo Không có mã được
phát ra trong đoạn này Các chỉ dẫn res, db, dw có thể được sử dụng để dự trữ không gian cho các biến Chỉ thị db để khởi tạo các byte liên tục cho RAM Chỉ dẫn dw để khởi tạo các
word liên tục cho RAM
idata
Trang 13y_cnt dw 20
flags db 0
prompt db “hello!”
[<label>] org <expr>
Chỉ dẫn này đặt gốc xuất phát chương trình Nếu trong chương trình không có sử dụng chỉ dẫn này, thì chương trình sẽ bắt đầu tại địa chỉ bằng 0
reset org 0x00
goto start org 0x100 start ; đoạn mã của chương trình
processor <processor_type>
Chỉ dẫn này để định loại bộ xử lý Ví dụ,
processor p18F4550
[<label>] udata [<RAM address>]
Chỉ dẫn này để tuyên bố sự bắt đầu của đoạn dữ liệu chưa được khởi tạo
var1 res 1
var2 res 2
[<label>] udata_shr [RAM addres>]
Đây là chỉ dẫn để công nhận sự bắt đầu của đoạn dữ liệu không được khởi tạo được chia
sẻ Nếu <label> không có thì đoạn mang tên “.udata_shr”
3.3.1 Xây dựng lưu đồ thuật toán
Trước khi lập trình, người lập trình cần phơi bày toàn bộ phương án cách giải quyết vấn
đề Phương án này được gọi là xây dựng lưu đồ thuật toán Lưu đồ thuật toán là xâu chuỗi các bước tính toán để truyền từ ngõ vào đến ngõ ra Thuật toán được xem như một công cụ để giải quyết vấn đề và mô tả một thủ tục tính toán cụ thể để đạt được mối quan hệ vào/ra Việc xây dựng lưu đồ thuật toán càng tốt sẽ làm cho người thiết kế sẽ viết chương trình càng tối
ưu Đối với chương trình lớn và phức tạp, khi nó đã được xây dựng lưu đồ thuật toán hoàn chỉnh, thì chương trình lớn này có thể chia nhỏ thành nhiều chương trình nhỏ và có thể phân cho nhiều người cùng viết chương trình
Các hình dạng ký hiệu theo chuẩn để biểu diễn trong một lưu đồ thuật toán như hình
Trang 14Hình 3.1: các ký hiệu chuẩn sử dụng trong lưu đồ thuật toán
Ví dụ 3.8: thiết kế lưu đồ thuật toán để tính tổng 3 số hạng tại các địa chỉ từ 0x10-0x12 Tổng
org 0x18
Trang 153.4.1 Thực hiện phép toán cộng
Lưu ý khi thực hiện phép cộng nếu kết quả bị tràn số sẽ ảnh hưởng đến các bit cờ trong thanh ghi trạng thái
Ví dụ 3.9: viết một chương trình để thực hiện cộng ba số được lưu trữ trong các thanh ghi dữ
liệu có các địa chỉ là 0x20, 0x30, 0x40 và kết quả tổng đặt vào thanh ghi dữ liệu có địa chỉ 0x50
Giải pháp: thuật toán cho việc cộng ba số như sau:
Cuối cùng lưu nội dung trong thanh ghi WREG vào vị trí bộ nhớ tại 0x50
Chương trình thi hành thuật toán này như sau:
addwf 0x30, W, A ; cộng giá trị tại 0x30 với nội dung WREG
Trang 16addwf 0x40, W, A ; cộng giá trị tại 0x40 với nội dung WREG movwf 0x50, A ; lưu tổng vào vị trí bộ nhớ 0x50
end
Ví dụ 3.10: viết một chương trình để thực hiện cộng các số nguyên 24 bit được lưu tại 0x10
0x12 và 0x13 0x15, kết quả lưu tại 0x20 0x22
addwf 0x13, W, A ; cộng và đặt tổng vào WREG
movwf 0x20, A ; lưu tổng tại 0x20 movf 0x11, W, A ; chép giá trị tại 0x11 vào WREG addwfc 0x14, W, A ; cộng có nhớ và đặt tổng vào WREG movwf 0x21, A ; lưu tổng tại 0x21
movf 0x12, W, A ; chép giá trị tại 0x12 vào WREG addwfc 0x15, W, A ; cộng có nhớ và đặt tổng vào WREG movwf 0x22, A ; lưu tổng tại 0x22
end
3.4.2 Thực hiện phép toán trừ
PIC18 có hai lệnh trừ hai toán hạng và hai phép trừ ba toán hạng Các lệnh trừ cũng tác động đến các bit cờ trong thanh ghi STATUS Tương tự các VĐK khác, PIC18 thi hành một lệnh trừ bằng cách thực hiện cộng bù 2 Khi số bị trừ lớn hơn số trừ thì việc mượn thêm để thực hiện trừ được là cần thiết, và các cờ của PIC18 trong tình huống này bằng cách xoá cờ
C của thanh ghi STATUS Các lệnh trừ ba toán hạng chủ yếu để hỗ trợ để thực hiện trừ nhiều byte
Ví dụ 3.11: viết một chương trình để thực hiện trừ cho 5 từ các các số được lưu tại các vị trí
Trang 17Bước 4
Lấy nội dung tại 0x12 trừ cho nội dung WREG và kết quả lưu vào tại 0x12
Bước 5
Lấy nội dung tại 0x13 trừ cho nội dung WREG và kết quả lưu vào tại 0x13
Chương trình hợp ngữ thực thuật toán này như sau:
subwf 0x10, F, A ; trừ cho 5 từ vị trí bộ nhớ 0x10 subwf 0x11, F, A ; trừ cho 5 từ vị trí bộ nhớ 0x11 subwf 0x12, F, A ; trừ cho 5 từ vị trí bộ nhớ 0x12 subwf 0x13, F, A ; trừ cho 5 từ vị trí bộ nhớ 0x13 end
Ví dụ 3.12: viết một chương trình để thực hiện trừ cho một số được lưu trữ từ địa chỉ 0x20
0x23 từ một số được lưu tại 0x10 0x13 và từng kết quả sẽ được lưu tại các địa chỉ 0x30 0x33
Giải pháp: xây dựng lưu đồ thuật toán như hình 3.2
END
Hình 3.2: lưu đồ thuật toán ví dụ 3.12
Trang 18subwf 0x10, W, A ; thực hiện trừ byte thứ nhất (byte thấp nhất)
PIC18 thực hiện toàn bộ số học dưới dạng nhị phân Chuỗi lệnh sau cho biết PIC18 thực hiện cộng hai số thập phân 31 và 47 và lưu tổng vào vị trí bộ nhớ 0x50:
Trang 19(1) Cộng thêm 0x6 cho mỗi con số tổng lớn hơn 9
(2) Cộng thêm 0x6 cho mỗi con số tổng mà có nhớ 1 cho lần thực hiện con số cao hơn
Bit 1 của thanh ghi STATUS là cờ nhớ số (Digit Carry Flag – DC) mà nó cho biết có
một sự nhớ từ bít 3 đến bit 4 của kết quả cộng Lệnh daw (decimal adjust WREG) để điều
chỉnh giá trị 8 bit trong thanh ghi WREG làm cho việc cộng hai biến ở dạng BCD dễ dàng hơn và cho kết quả chính xác Việc thực hiện cộng thập phân nhiều byte cũng có thể thực hiện với lệnh daw
Ví dụ 3.13: viết một chương trình để thực hiện cộng hai số được lưu trữ tại địa chỉ 0x23 và
Ví dụ 3.14: viết một chương trình để thực hiện cộng số được lưu trữ tại địa chỉ từ 0x10
0x13 với số được lưu từ 0x14 0x17 và tổng được lưu từ 0x20 0x23
Giải pháp: nhằm mục đích bảo đảm tổng cũng ở dạng thập phân, sự điều chỉnh thập phân
phải được thực hiện sau khi có của một cặp byte