Một số ví dụ lập trình hợp ngữ LC3 | Tin học đại cương | Đại học Bách Khoa Hà Nội

Một số ví dụ lập trình hợp ngữ LC3 | Tin học đại cương | Đại học Bách Khoa Hà Nội. Tài liệu được biên soạn giúp các bạn tham khảo, củng cố kiến thức, ôn tập và đạt kết quả cao kết thúc học phần. Mời các bạn đọc đón xem!

M þT S VÍ DĀ L¾P TRÌNH H P NGþ LC-3
Trn Quc Ti ến Dũng
B u khimôn Điề n t n động, Khoa Điệ Điện t
Trường Đạ ọc Bách Khoa, ĐHQG TP.HCMi h
1. Nh c li v t p l nh LC-3 ¿
Tp l nh LC-3 (LC-3 ISA) bao g m 15 l nh. M i l nh chi u dài là 16 bit bao g m 4 bit
đầu là mã lnh (opcode) và 12 bit sau là các toán hng (operands). Tùy thuc vào lnh mà có
th có 1 ho u toán h ng. c nhi
Có 5 cách định v địa ch trong LC-3:
- Tc thi (immediate)
- Thanh ghi (register)
- PC-relative
- Gián tiếp (indirect)
- Base + offset
3 nhóm l nh trong LC- nh th c thi (NOT, ADD, AND), nhóm l nh di 3, đó nhóm lệ
chuyn d li u (LD, ST, LDI, STI, LDR, STR, LEA) nhóm l u khi n (BR, ệnh điề
JMP/RET, JSR/JSRR, RTI, TRAP).
a. Nhóm l nh th c thi:
Ch bao g m 3 l nh là NOT, ADD, AND.
d 1: Tr hai thanh ghi R0 R1, lưu
kết qu vào thanh ghi R0.
NOT R1,R1
ADD R1,R1,#1
ADD R0,R0,R1
Ví d 2: Th c hi n phép OR hai thanh ghi
R0 và R1, lưu kết qu vào thanh ghi R0.
NOT R0,R0
NOT R1,R1
AND R0,R0,R1
NOT R0,R0
d 3: Chuy n d li u t thanh ghi R0
sang thanh ghi R4
Cách 1: ADD R4,R0,#0
Cách 2: AND R4,R0,#-1
d 4: Kh i t o thanh ghi R2 v i giá tr
ban đầu là 10.
AND R2,R2,0
ADD R2,R2,#10
b. Nhóm l nh di chuy n d li u:
Có 2 lo i di chuy n d li u: l y d li u t b nh n p vào thanh ghi (LOAD) l y d li u
t thanh ghi lưu vào b nh (STORE). Như vậy các lnh di chuyn d liu s đi theo cặp.
Tùy thu nh v s có m t l nh riêng. ộc vào cách đị địa ch
Mã l nh:
Cu trúc l nh:
Kiểu định
v a ch đị
Lnh LOAD ng tương ứ
Lnh STORE ng tương ứ
Ghi chú
PC-
relative
LD Rx,PCoffset9
Rx M[PC + PCoffset9]
ST Rx, PCoffset9
M[PC + PCoffset9] Rx
Tm tham
chiếu tối đa
là 512 byte
xung quanh
giá tr PC.
Indirect
LDI Rx, PCoffset9
Rx M[M[PC + PCoffset9]]
STI Rx, PCoffset9
M[M[PC + PCoffset9]] Rx
Tm tham
chiếu là toàn
b b nh
64K.
Base +
offset
LDR Rx,Ry,offset6
Rx ← M[Ry + offset6]
STR Rx,Ry, offset6
M[Ry + offset6] ← Rx
Lưu ý:
- Các phép c ng trong LC- u s 2, v c khi c ng ph i m r ng d u. 3 đề ậy trướ
Đặ c bi ng hệt lưu ý các trườ p giá tr PCoffset9 và offset6 là s âm.
- Sau pha l y l nh, giá tr PC đã được tăng thêm 1.
Lnh LEA không có tác d ng di chuy n d li u, tuy nhiên giúp sinh ra giá tr a ch tham đị để
chiếu đến.
Các b n có th tham kh o các ví d trong giáo trình.
c. Nhóm l u khi n: ệnh điề
Trong chương trình môn họ ần chú ý đế ệnh điềc, các bn ch c n 2 l u khin chính lnh r
nhánh (BR) và l nh TRAP. Các l nh còn l i các b n có th xem thêm trong giáo trình.
LC-3 cung c u ki n (condition code) N, Z, P. Sau m i l li u vào ấp 3 điề ệnh lưu dữ
thanh ghi DR, các điề thay đổu kin này s i ph thuc vào kết qu trong thanh ghi DR
vừa được lưu. Nếu kết qu s dương thì c P được bt (P positive), các c còn li tt.
Tương tự cho trường hp c Z (zero) và c N (negative).
Ví d 5: Sau l nh thì d li y c AND R1,R1,#0 ệu được ghi vào thanh ghi DR là 0, như v
Z được bt lên.
d 6: Gi s a d li u #8, sau l nh thì d thanh ghi R1 đang chứ ADD R1,R1,#-10
liu trong thanh ghi DR là #-2 là s y c âm, như vậ N s được bt lên.
Ví d 7: Sau l nh thì các c u ki n s i. Lý do là vì l nh ST SR R2,#-10 điề không thay đổ
không lưu dữ liu vào thanh ghi.
Trong LC-3, nh ng l nh có th t li ục lưu dữ ệu vào thanh ghi đó NOT, AND, ADD, LD,
LDR, LDI, LEA, nh ng l nh còn l i ch c ch n không làm tha y đổi các điều kin. Da
vào các mã điề ệnh đểu kin này, chúng ta có th thiết lp r nhánh tùy vào yêu cu của đề. L
r nhánh là l nh BR (opcode 0000). Ba bit ti u ki n (n, z, p), 9 bit còn ếp theo đ xác định điề
l ếi xác định độ di PCoffset. N u bit 11 (bit ng v i mã l nh n) b ng 1, PC s nh y khi c N
được b khi bit 10 và bit 9 b ng 1. Có th có nhiật lên. Tương tự ều hơn 1 bit trong 3 bit n, z, p
bằng 1, khi đó điều kin s là <hoặc=.
Ví d 8: Mã l nh u c Z ho P b ng 1 thì câu 0000 011 000001000 có ý nghĩa là nế c c
lnh ti p theo th c thi s n m PC + #8. ế địa ch
Ta có bng l nh h p ng ng: tương ứ
n
z
p
Ghi chú
0
0
0
Lệnh này không có ý nghĩa thực thi (tương ng vi
lnh NOP No Operation)
0
0
1
0
1
0
1
0
0
0
1
1
1
0
1
1
1
0
1
1
1
Lnh y s luôn nh y, không quan tr ng các c
điều kin. Khi lp trình hp ng th ng BR
thay cho BRnzp.
Ví d 9: Vi b u t x3010, ki m tra n n câu l nh ết chương trình ắt đầ ếu R0 dương thì nhảy đế
đị a ch x3020.
x3010: ADD R0,R0,#0
x3011: BRp x0E
Nhn xét: Bởi ta chưa biết các c điều kiện trước đó ứng v i thanh ghi nào c , vì v y không
th đặt l nh x3010: BRp x0F c. Ph i g i 1 lđượ ệnh để set các c u ki n d a vào thanh điề
ghi R0 trước, sau đó mới kim tra các c dùng l nh BRp. Câu l nh x3010 không có ý nghĩa
thực thi, tuy nhiên có ý nghĩa set các cờ điều ki n theo thanh ghi mong mu n.
Ví d 10: So sánh hai thanh ghi R0 và R1, n u thanh ghi R0 l c b ng R1 thì nh y ế ớn hơn ho
đế đị n lnh a ch x3020. Chương trình bắt đầu t x3050.
Phân tích: so sánh ta s ph i dùng phép tr hai thanh ghi. để
x3050: NOT R1,R1
x3051: ADD R1,R1,#1
x3052: ADD R0,R1,R1
Phân tích: sau l nh v a r i, thanh ghi k t qu u c ế R0 đó chính là hiệ ủa R0 và R1 trước đó, vì
vy ta không c n ph i g i l ệnh như ví dụ 9 na. Ti p theo s là l nh x3053: BRzp PCoffset9. ế
Để tính PC offset, ta c dần tính độ i bng cách tr thanh ghi đích cho thanh ghi PC. Chú ý là
sau pha l y l y PC = x3054. ệnh thì PC được tăng thêm 1, như vậ
Lúc y PCoffset = x3020 x3054 = xFFCC (b qua vi c b tràn s ), rút g n l i 9 bit (vì l nh
này ch có 9 bit cho ph n offset) là x1CC:
x3053: BRzp x1CC
Mt cách khác các b n tính phép tính trên s c PCoffset = x- y có th vi t thu đượ 34, như vậ ế
lnh:
x3053: BRzp x-34
T câu l nh r nhánh này, ta th s d gi m b t kh ng l p ụng phương pháp lặp để ối lượ
trình. hai phương pháp để ến đếm (tương lp, cách th nht dùng bi ng vi vòng lp
for mà các bạn đã đượ ọc trước đây), cách còn lạc h i là dùng tr canh (tương ứng vi vòng lp
while). Các b n th tham kh o thêm trong giáo trình. Trong bài vi t này trình y hai ế
d v hai cách l p.
Ví d 11: Vi t n u t x3020 th c hi n nhân giá tr trong thanh ghi R0 ế đoạ chương trình bắt đầ
với 8, sau đó lưu vào thanh ghi R1 và nhy đến câu lnh tại địa ch x3080.
Phân tích: u tiên ta s kh i t o thanh ghi R2 b ng 8, thanh ghi R1 bđầ ằng 0. Sau đó mỗi bước
ta c ng vào thanh ghi R1 b ng v i giá tr c a R0 gi n khi R2 v a ảm R2 đi 1 đơn vị. Đế
bng 0 thì nh n câu l nh x3080. ảy đế
Địa ch
Lnh ho li u c d
Gii thích
x3020
AND R1,R1,#0
Khi t o R1 = #0
x3021
ADD R2,R1,#8
Khi t o R2 = #8
x3022
ADD R1,R1,R0
x3023
ADD R2,R2,#-1
x3024
BRp x-3
Nếu R2 còn dương thì nhảy v câu lnh x3022
x3025
BR x5A
Ngược li, nhảy đến câu lnh ti x3060
Ví d 12: Cho m t chu i t b u t a ch x3100, vi m s t c a ắt đầ ại đị ết chương trình đế
chuỗi đó. Cho biết du hiu nhn biết chui kí tkí t có mã ASCII bng 0 và không tính
t này vào chi u dài c a chu i. Đoạn chương trình vi t bế ắt đầu tại x3020, sau khi đếm xong
thì nhảy đến địa ch x3080.
Địa ch
Lnh ho li u c d
Gii thích
x3020
LEA R1,x7F
Tạo địa ch đầu R1 = x3100
x3021
AND R2,R2,#0
Khi t o bi m R2 = #0 ến đế
x3022
LDR R0,R1,#0
Ly kí t
x3023
BRz x5C
Nếu kí t b ng 0, ng m và nh n x3080 ừng đế y đế
x3024
ADD R2,R2,#1
Nếu kí t khác 0, tăng biến đếm thêm 1, tăng địa ch thêm
1 và nh y v l i câu l nh l y kí t
x3025
ADD R1,R1,#1
x3026
BR x-5
Lnh cu i cùng l nh TRAP (opcode 1111). l nh y s g i c th t c s n trong
chương trình. Có 6 mã chương trình đưc h tr trong phn mm Simulator.exe ca LC-3.
Trap
vector
Lnh h p ng
Lnh h p
ng rút gn
Chức năng
x20
TRAP x20
GETC
Đọc 1 t t bàn phím, kí t này không hin ra
màn hình. Mã ASCII c a t v a nh p được lưu
vào thanh ghi R0.
x21
TRAP x21
OUT
Xut kí t t thanh ghi R0 (mã ASCII) ra màn hình.
x22
TRAP x22
PUTS
Xut m ng t a ch ra màn hình, đị b u c a ắt đầ
mng thanh ghi R0. M i ô nh tương ng vi 1
kí t. In đến khi xut hin kí t bng 0 trong mng.
x23
TRAP x23
IN
Đọc 1 kí t t bàn phím, kí t này được hi n ra màn
hình. ASCII c a t v a nh ập được lưu vào
thanh ghi R0.
x24
TRAP x24
PUTSP
Xut m ng t a ch ra màn hình, đị b u c a ắt đầ
mng là thanh ghi R0. M i ô nh tương ng vi 2
kí t. Kí t in đầu nm bit [15:8], kí t sau nm
bit [7:0]. n khi xu t hi n t b ng 0 trong In đế
mng.
x25
TRAP x25
HALT
Dừng chương trình
Ví d 13: Vi p 2 t s (t n 9) t bàn phím, tính t ng 2 s xu t ết chương trình nh 0 đế
ra màn hình.
Địa ch
Lnh ho li u c d
Gii thích
x3000
IN
Nhp kí t th nh t
x3001
LD R1,x13
Ly h ng s chuy n t mã ASCII sang s và lưu vào R1.
x3002
NOT R1,R1
Chuyn thành s âm
x3003
ADD R1,R1,#1
x3004
ADD R2,R0,R1
Lưu kế ập vào R2, đểt qu s va nh thanh ghi R0 nhn
kí t m i
x3005
IN
Nhp kí t th hai
x3006
ADD R2,R0,R2
Cng hai s v p v a nh i nhau.
x3007
ADD R2,R2,R1
x3008
ADD R3,R2,#-10
Kim tra xem t ng l u có thì ớn hơn 10 hay không, nế
nhảy đến câu lnh x3011
x3009
BRn x7
x300A
LD R0,xA
Xut l t hai ký t ần lượ
x300B
ADD R0,R0,#1
x300C
OUT
x300D
LD R0,x7
x300E
ADD R0,R0,R3
x300F
OUT
x3010
BR x3
Nhảy đến ô x3014
x3011
LD R0,x3
Xut 1 kí t .
x3012
ADD R0,R0,R2
x3013
OUT
x3014
HALT
Dừng chương trình
x3015
x0030
Hng s chuy n t mã ASCII sang s (x30 = #48)
2. L ¿p trình h p ng LC-3 ÿ ÿ
a. Lnh hp ng trong LC-3:
Mt l nh h p ng trong LC-3 bao g m 4 thành ph n:
Nhãn
Mã l nh
Toán h ng
; Chú thích
Trong đó phần bt buc phi lnh. Tùy vào lnh mà có thhoc không
toán h ng. Hai ph ho ần <Nhãn= <Chú thích= thể ặc không. Trong đó chú thích sử
dụng để ải thích ý nghĩa c ột đoạ ười đọ gi a mt lnh hoc m n lnh. Giúp cho ng c d dàng
nm b ng c i l p trình. B t bu i là d u ch m ph y (;). ắt ý tưở ủa ngư ộc trước chú thích ph
Ví d 14: Câu l nh
LAP ADD R1,R1,#-1 ;giam R1 xuong 1 don vi
Trong đó:
- LAP là nhãn c a l nh
- ADD là mã l nh
- R1,R1,#-1 là các toán h ng c ng a lệnh tương
- ;giam R1 xuong 1 don vi là chú thích v nh ý nghĩa của l
Ví d 15: Câu l nh có mã l nh, không có các thành ph n còn l IN ch i.
b. Nhãn:
Nhãn các tên tượng trưng được dùng để xác đị nh các ô nh được tham kho ti trong
chương trình. Trong hợp ng LC-3, mt nhãn th được to t mt ti 20 ký s hay ký t,
và b u b ng m t ký tắt đầ ự, như LAPLAI, KETTHUC, LAP100,….
Có hai lý do c n cho vi c tham kh o m t v trí trong b nh ớ, đó là
- Ô nh v a m t l nh r nhánh. trí đó chứa đích củ
- Ô nh v trí t giá tr c c n đó cha m ần đư ạp hay lưu.
Ví d 16: Gi s r ng các c u ki c set theo thanh ghi R0, vi điề ện đã đượ ết đoạn chương trình
tiếp theo ki m tra n u R0 l n ế hơn 0 thì thự ộng R1 thêm 1 đơn vị ếu R0 bé hơn 0 thì c hin c , n
cộng R2 thêm 1 đơn vị, nếu R0 bng 0 thì c ộng R3 thêm 1 đơn vị, sau đó dừng chương trình.
BRp
LON_HON_0
BRn
BE HON 0
ADD
R3,R3,#1
BR
KET_THUC
LON_HON_0
ADD
R1,R1,#1
BR
KET THUC
BE_HON_0
ADD
R2,R2,#1
KET_THUC
HALT
Như vậy vic dùng nhãn s giúp cho b hp dch t động tính các giá tr offset cho các lnh
có ch a giá tr y (ví d l i l p trình s c vi c ph i t ệnh BR, LD, LEA, …). Ngư tránh đượ
tính tay các độ d c bi t là tránh vi c ph i tính l dời, đặ ại độ i khi thêm các dòng l nh vào gi a
chương trình.
c. Các mã gi :
B h p d ch LC-3 là m u vào là chu i ký t bi u di n m ột chương trình lấy đầ ột chương trình
đượ c viết bng h p ng LC-3, và d ch nó ra thành m cột chương trình p kiến trúc tp lnh
(ISA) c a LC-3.
gi (pseudo-ops) giúp cho b d ch th c hi n nhi m v c g i b ng m t tên y, còn đượ
khác là hướng dn dch (assembler directives).
B hp d ch LC-3 g ồm năm mã giả: .ORIG, .FILL, .BLKW, .STRINGZ, và .END. Lưu ý tất
c mã gi u có d u ch u tiên c a nó. này đề ấm như là ký tự đầ
Mã gi
Ví d
Chức năng
.ORIG
.ORIG x3000
Ch cho b h p dch bi t v trí ô nhế b u c a ắt đ
chương trình. Câu lệnh đầu tiên đượ ịch cũng sẽc d
đặ t v trí đó.
Như ở ví d , câu l ệnh đầu tiên được d ch s được đặt
ti v trí x3000.
.FILL
.FILL x1234
Yêu c u b h p d dành ô nh ti p theo trong ịch để ế
chương trình để lưu d liu. Giá tr khi to ca ô
nh này là toán h ng c a mã gi .
Như ở ví d, ô nh tiếp theo s đưc khi to giá tr
x1234.
.BLKW
MANG .BLKW x10
Yêu c u b h p d dành m ng ô nh b ng ịch để ột lượ
vi toán h ng c a mã gi d li u. để lưu trữ
Như ở được để dành để d, 16 ô nh tiếp theo s
lưu dữ li u. Nhãn c a l nh này ( ) s MANG tương ứng
vi v trí ô nh u tiên trong kh đầ i.
.STRINGZ
MANG_KI_TU
.STRINGZ
<Hello world!=
Yêu c u b h p d ch kh i t o n+1 ô nh , t rong đó n
ô ng v i chi u dài c a m ng ô cu i cùng mang
giá tr x0000 bi u di n giá tr cu i c a m ng,
th để làm tr canh cho các thu t toán l p.
Như ởd, b nh đưc yêu c dành m ng có ầu để
13 ô nh . Nhãn c a l ng v i v trí ô nh ệnh tương
đầu tiên.
.END
Báo cho b h p d ch bi t v trí cu i cùng c ế ủa chương
trình. T t c các l nh sau mã này s không được d ch.
Ví d 17: Vi p ng hoàn ch nh th n các yêu c u sau: ết chương trình hợ c hi
- Nhp l t hai s (t n 9) t bàn phím. ần lượ 0 đế
- Tính tng c a hai s này và in ra màn hình theo cú pháp: <Tong cua hai so la: XX=
Trong đó XX tương ứng v i k ết qu.
- Lưu kế i địt quy vào 3 ô nh t a ch x4000, x4001, x4002 theo th t: s nhp th
nht, s nh p th hai, t ng c a 2 s.
.ORIG
x3000
IN
;nhp kí t th nh t
LD
R1,ASCII_0
;chuyn ascii
thành s
NOT
R1,R1
ADD
R1,R1,#1
ADD
R2,R0,R1
;lưu giá trị s vào
R2
IN
ADD
R3,R0,R1
;và R3
ADD
R4,R2,R3
;tng c a 2 s
LD
R0,DIA_CHI_LUU
;lấy đị lưu dữa ch
liu
STR
R2,R0,#0
;lưu i d ng base +
offset
STR
R3,R0,#1
STR
R4,R0,#2
LEA
R0,STROUT
;ly ô nh đia chỉ
ca chui thông báo
PUTS
;xut chuỗi ra trước,
xut kết qu sau
LD
R1,ASCII_0
ADD
R5,R4,#-10
;kim tra t ng bao
nhiêu ch s
BRzp
XUAT_2_CHU_SO
ADD
R0,R4,R1
;xut 1 ch s
OUT
BR
KET_THUC
XUAT_2_CHU_SO
ADD
R0,R1,#1
;ch s đầu tiên ch c
chn là 1
OUT
ADD
R0,R5,R1
;sau khi tr 10 thì
R5 ch a ch s hàng
đơn vị
OUT
KET_THUC
HALT
ASCII_0
.FILL
#48
DIA CHI LUU
.FILL
x4000
STROUT
.STRINGZ
<Tong cua hai so la: <
.END
d. Lp trình s d ng LC3Edit.exe và mô ph ng dùng Simulate.exe
S d ng ph l p trình l i ví d v i. n mềm LC3Edit.exe để a r
Do chương trình được viết b ng h p ng , ph ải lưu chương trình với tên file có đuôi là <.asm=
và ph i b m vào nút biên d ch. N u không có l i, ta nh t qu : để ế ận đưc kế
Sau đó, mở ần mêm Simulate.exe để ph chy th.
M File Load Program (Ctrl + L) ho c nút , ch n file object v c LC3Edit biên ừa đượ
dịch, ta thu được kết qu như hình i. B m vào nút để chạy chương trình. Sau khi chạy
xong, để ặc đơn giản hơn thể chy li mt ln na ta phi Load Program li, ho chn vào
File Reload Program. Ngoài ra có th ch n ch xem giá tr t i m t ô ức năng <Jump to:= để
nh b t kì.
Mt k t qu ví d khi t ng có 2 ch s : ế
Mt k t qu ví d khi t ng có 1 ch s : ế
e. M t s ví d khác:
Trong phn này s trình bày m t s ví d n v l p trình h p ng LC-3. đơn giả
Ví d 18: Vi c hi n nh p 2 s (t n 9) t bàn phím, tính hi u c a 2 s ết chương trình thự 0 đế
này và in ra màn hình.
Phân tích: Ta th y r ng hi u c a 2 s 1 ch s ch c ch ắn cũng chỉ1 ch s . Tuy nhiên hi u
này có th là s âm, vì v y c n ph i dùng câu l nh r nhánh. Khi g ng h p s âm, ta in ặp trườ
ra d n k t qu thành s (bù 2) và in ra màn hình. ấu <-<, sau đó chuyể ế ơng
.ORIG
x3000
IN
ADD
R1,R0,#0
;copy d li u t R0
sang R1, ch a l i v
trí R0 đ nhp t
tiếp theo
IN
NOT
R0,R0
ADD
R0,R0,#1
ADD
R1,R1,R0
;R1 := R1-R0
BRzp
IN_CHU_SO
LD
R0,MINUS_SIGN
;nếu là s âm, chuy n
thành s dương in
du <-<
OUT
NOT
R1,R1
ADD
R1,R1,#1
IN_CHU_SO
LD
R0,ASCII_0
ADD
R0,R0,R1
OUT
HALT
MINUS_SIGN
.FILL
#45
;= <-
ASCII_0
.FILL
#48
;=0=
.END
Ví d 19: Viết chương trình thực hin nhp 2 s (t 0 đến 9) t bàn phím, tính tích hai s này
và in ra màn hình.
Phân tích: Có 2 thu t toán chính c n ph i th n trong bài này: c hi
- S dng l p bi ết trước s l tính tích c a hai s ần để
- S d ng l p không bi c s l tách m t s b t kì thành 2 ch s hàng ch c và ết trướ ần để
hàng đơn vị
.ORIG
x3000
IN
LD
R1,ASCII_0M
;ly h ng s chuy n
t mã ASCII sang s
ADD
R2,R0,R1
;copy d li u s v a
nhp R2
IN
ADD
R3,R0,R1
AND
R4,R4,#0
;tính tích R2 x R3
LAP
ADD
R2,R2,#-1
BRn
TACH SO
ADD
R4,R4,R3
BR
LAP
TACH_SO
AND
R2,R2,#0
;tách ch s hàng
chục và hàng đơn vị
LAP2
ADD
R4,R4,#-10
BRn
TIEP
ADD
R2,R2,#1
;R2 ch s hàng
chc
BR
LAP2
TIEP
ADD
R3,R4,#10
;R3 ch s hàng
đơn vị
LD
R1,ASCII_0
ADD
R2,R2,#0
;kim tra R2 b ng 0
thì b qua, không in
BRz
XUAT DON VI
ADD
R0,R2,R1
OUT
XUAT DON VI
ADD
R0,R3,R1
OUT
HALT
ASCII_0
.FILL
#48
;=0=
ASCII 0M
.FILL
#-48
.END
Ví d 20: So sánh hai s 1 ch s c nh p t bàn phím (l t nh p vào là a và b) đượ ần lượ
- Nếu a > b thì in ra màn hình: A lon hon B < =
- Nếu a < b thì in ra màn hình: A be hon B < =
- Nếu a = b thì in ra màn hình Hai so bang nhau < =
Phân tích: Bài này không quá khó, ch c n l y hi u hai kí t v c nh n vào và r nhánh ừa đượ
hai l n.
.ORIG
x3000
IN
ADD
R1,R0,#0
;copy d li u t R0
sang R1
IN
NOT
R0,R0
ADD
R0,R0,#1
ADD
R1,R1,R0
;R1 := R1-R0
BRn
BE_HON
BRp
LON HON
LEA
R0,STR_BANG
;2 so bang nhau
BR
IN_CHUOI
BE_HON
LEA
R0,STR_BE
BR
IN CHUOI
LON_HON
LEA
R0,STR_LON
IN_CHUOI
PUTS
HALT
STR_BE
.STRINGZ
< =A be hon B
STR_LON
.STRINGZ
< =A lon hon B
STR BANG
.STRINGZ
< =Hai so bang nhau
.END
Ví d 21: M r ng ví d trên, in ra màn hình giá tr l n nh t, giá tr nh t c a 3 s c đượ
nhp t bàn phím.
Phân tích: S d ng phép l p bi c s l n, th m r ng thay s 3 b i s ng b t kì. ết trướ lượ
Vì các phép so sánh phép tr nên th dùng tr c ti p không c n ph i chuy n t ế
ASCII sang s.
Chức năng của các bi ến trong chương trình:
- R1: lưu số ln lp còn li
- R2: lưu giá trị nh nht
- R3: lưu giá trị ln nht
.ORIG
x3000
LD
R1,SO_LAN_LAP
;s l p n l
LD
R2,INIT_MIN
;khi t o giá tr nh
nht
LD
R3,INIT_MAX
;khi t o giá tr l n
nht
LAP
IN
NOT
R4,R0
;chuyn R0 thành s
ầm để tính hi u
ADD
R4,R4,#1
ADD
R5,R2,R4
;so sánh v i giá tr
nh nh t
BRnz
TIEP_TUC_1
ADD
R2,R0,#0
TIEP TUC 1
ADD
R5,R3,R4
BRzp
TIEP_TUC_2
ADD
R3,R0,#0
TIEP_TUC_2
ADD
R1,R1,#-1
;giảm R1 đi 1 đơn vị,
nếu bng 0 thì b t
đầu in d li u
BRp
LAP
LEA
R0,STR MIN
;in min và max
PUTS
ADD
R0,R2,#0
OUT
LEA
R0,STR MAX
PUTS
ADD
R0,R3,#0
OUT
HALT
SO_LAN_LAP
.FILL
#3
INIT_MIN
.FILL
#57
INIT MAX
.FILL
#48
STR_MIN
.STRINGZ
< <So be nhat la:
STR_MAX
.STRINGZ
< <\nSo lon nhat la:
.END
Ví d 22: Nh p m t chu i các s m t ch s t bàn phím, k t thúc khi nh p vào t #. ế
In ra màn hình t ng c a dãy s v c nh p (gi s r ng t ng c a y này nh ừa đượ hơn 100).
Lưu các số vừa được nhp vào vào b nh t địa ch x4000, kết thúc bng giá tr <#=.
Cho bi t mã ASCII c a kí t là x23. ế <#=
.ORIG
x3000
LD
R1,ASCII_#M
LD
R2,ASCII_0M
LD
R3,DIA CHI DAU
AND
R4,R4,#0
;tng ca dãy
LAP
IN
ADD
R5,R0,R1
BRz
NGUNG LAP
ADD
R5,R0,R2
STR
R5,R3,#0
;lưu giá trị vào b
nh
ADD
R3,R3,#1
;tăng địa ch ô nh
lên 1
ADD
R4,R4,R5
;tính tng
BR
LAP
NGUNG_LAP
STR
R0,R3,#0
;lưu tự # vào ô
nh, không c n thi t ế
phải tăng địa ch n a
LEA
R0,STR OUT
PUTS
AND
R2,R2,#0
;tách ch s hàng
chục và hàng đơn vị
LAP2
ADD
R4,R4,#-10
BRn
TIEP
ADD
R2,R2,#1
;R2 ch s hàng
chc
BR
LAP2
TIEP
ADD
R3,R4,#10
;R3 ch s hàng
đơn vị
LD
R1,ASCII 0
ADD
R2,R2,#0
;kim tra R2 b ng 0
thì b qua, không in
BRz
XUAT_DON_VI
ADD
R0,R2,R1
OUT
XUAT_DON_VI
ADD
R0,R3,R1
OUT
HALT
ASCII_0
.FILL
#48
;=0=
ASCII_0M
.FILL
#-48
ASCII #M
.FILL
x-23
; #= =
DIA_CHI_DAU
.FILL
x4000
STR_OUT
.STRINGZ
< <Tong cua day so la:
.END
- H T -
| 1/14

Preview text:

MT S VÍ DĀ L¾P TRÌNH HþP NGþ LC-3 Trần Quốc Ti ến Dũng
B môn Điều khin t động, Khoa Điện Điện t
Trường Đại học Bách Khoa, ĐHQG TP.HCM
1. Nhc li v t¿p lnh LC-3
Tập lệnh LC-3 (LC-3 ISA) bao gồm 15 lệnh. Mỗi lệnh có chiều dài là 16 bit bao gồm 4 bit
đầu là mã lệnh (opcode) và 12 bit sau là các toán hạng (operands). Tùy thuộc vào lệnh mà có
thể có 1 hoặc nhiều toán hạng.
Có 5 cách định vị địa chỉ trong LC-3: - Tức thời (immediate) - Thanh ghi (register) - PC-relative - Gián tiếp (indirect) - Base + offset
Có 3 nhóm lệnh trong LC-3, đó là nhóm lệnh thực thi (NOT, ADD, AND), nhóm lệnh di
chuyển dữ liệu (LD, ST, LDI, STI, LDR, STR, LEA) và nhóm lệnh điều khiển (BR,
JMP/RET, JSR/JSRR, RTI, TRAP). a. Nhóm lệnh thực thi:
Chỉ bao gồm 3 lệnh là NOT, ADD, AND.
Ví d 1: Trừ hai thanh ghi R0 và R1, lưu
Ví d 3: Chuyển dữ liệu từ thanh ghi R0
kết quả vào thanh ghi R0. sang thanh ghi R4 NOT R1,R1 Cách 1: ADD R4,R0,#0 ADD R1,R1,#1 Cách 2: AND R4,R0,#-1 ADD R0,R0,R1
Ví d 2: Thực hiện phép OR hai thanh ghi
Ví d 4: Khởi tạo thanh ghi R2 với giá trị
R0 và R1, lưu kết quả vào thanh ghi R0. ban đầu là 10. NOT R0,R0 AND R2,R2,0 NOT R1,R1 ADD R2,R2,#10 AND R0,R0,R1 NOT R0,R0
b. Nhóm lệnh di chuyển dữ liệu:
Có 2 loại di chuyển dữ liệu: lấy dữ liệu từ bộ nhớ nạp vào thanh ghi (LOAD) và lấy dữ liệu
từ thanh ghi lưu vào bộ nhớ (STORE). Như vậy các lệnh di chuyển dữ liệu sẽ đi theo cặp.
Tùy thuộc vào cách định vị địa chỉ sẽ có một lệnh riêng. Mã lệnh: Cấu trúc lệnh: Kiểu định Lệnh LOAD tương ứng Lệnh STORE tương ứng Ghi chú vị địa chỉ Tầm tham chiếu tối đa PC- LD Rx,PCoffset9 ST Rx, PCoffset9 là 512 byte relative Rx ← M[PC + PCoffset9] M[PC + PCoffset9] ← Rx xung quanh giá trị PC. Indirect LDI Rx, PCoffset9 STI Rx, PCoffset9 Tầm tham
Rx ← M[M[PC + PCoffset9]] M[M[PC + PCoffset9]] ← Rx chiếu là toàn Base + LDR Rx,Ry,offset6 STR Rx,Ry, offset6 bộ bộ nhớ offset Rx ← M[Ry + offset6] M[Ry + offset6] ← Rx 64K. Lưu ý:
- Các phép cộng trong LC-3 đều là số bù 2, vì vậy trước khi cộng phải mở rộng dấu.
Đặc biệt lưu ý các trường hợp giá trị PCoffset9 và offset6 là số âm.
- Sau pha lấy lệnh, giá trị PC đã được tăng thêm 1.
Lệnh LEA không có tác dụng di chuyển dữ liệu, tuy nhiên giúp sinh ra giá trị địa chỉ để tham chiếu đến.
Các bạn có thể tham khảo các ví dụ trong giáo trình.
c. Nhóm lệnh điều khiển:
Trong chương trình môn học, các bạn chỉ cần chú ý đến 2 lệnh điều khiển chính là lệnh rẽ
nhánh (BR) và lệnh TRAP. Các lệnh còn lại các bạn có thể xem thêm trong giáo trình.
LC-3 cung cấp 3 mã điều kiện (condition code) là N, Z, P. Sau mỗi lệnh có lưu dữ liệu vào
thanh ghi DR, các mã điều kiện này sẽ thay đổi phụ thuộc vào kết quả trong thanh ghi DR
vừa được lưu. Nếu kết quả là số dương thì cờ P được bật (P – positive), các cờ còn lại tắt.
Tương tự cho trường hợp cờ Z (zero) và cờ N (negative).
Ví d 5: Sau lệnh AND R1,R1,#0 thì dữ liệu được ghi vào thanh ghi DR là 0, như vậy cờ Z được bật lên.
Ví d 6: Giả sử thanh ghi R1 đang chứa dữ liệu là #8, sau lệnh ADD R1,R1,#-10 thì dữ
liệu trong thanh ghi DR là #-2 là số âm, như vậy cờ N sẽ được bật lên.
Ví d 7: Sau lệnh SR R2,#-10 thì các cờ điều kiện sẽ không thay đổi. Lý do là vì lệnh ST
không lưu dữ liệu vào thanh ghi.
Trong LC-3, những lệnh có thủ tục lưu dữ liệu vào thanh ghi đó là NOT, AND, ADD, LD,
LDR, LDI, LEA, những lệnh còn lại chắc chắn không làm thay đổi các mã điều kiện. Dựa
vào các mã điều kiện này, chúng ta có thể thiết lập rẽ nhánh tùy vào yêu cầu của đề. Lệnh để
rẽ nhánh là lệnh BR (opcode 0000). Ba bit tiếp theo để xác định điều kiện (n, z, p), 9 bit còn
lại xác định độ dời PCoffset. Nếu bit 11 (bit ứng với mã lệnh n) bằng 1, PC sẽ nhảy khi cờ N
được bật lên. Tương tự khi bit 10 và bit 9 bằng 1. Có thể có nhiều hơn 1 bit trong 3 bit n, z, p
bằng 1, khi đó điều kiện sẽ là Ví d 8: Mã lệnh 0000 011 000001000 có ý nghĩa là nếu cờ Z hoặc cờ P bằng 1 thì câu
lệnh tiếp theo thực thi sẽ nằm ở địa chỉ PC + #8.
Ta có bảng lệnh hợp ngữ tương ứng: n z p Mã lệnh hợp ngữ Ghi chú 0 0 0
Lệnh này không có ý nghĩa thực thi (tương ứng với lệnh NOP – No Operation) 0 0 1 BRp PCoffset9 0 1 0 BRz PCoffset9 1 0 0 BRn PCoffset9 0 1 1 BRzp PCoffset9 1 0 1 BRnp PCoffset9 1 1 0 BRnz PCoffset9 1 1 1 BRnzp PCoffset9
Lệnh này sẽ luôn nhảy, không quan trọng các cờ
điều kiện. Khi lập trình hợp ngữ có thể dùng BR thay cho BRnzp.
Ví d 9: Viết chương trình bắt đầu từ x3010, kiểm tra nếu R0 dương thì nhảy đến câu lệnh ở địa chỉ x3020. x3010: ADD R0,R0,#0 x3011: BRp x0E
Nhận xét: Bởi vì ta chưa biết các cờ điều kiện trước đó ứng với thanh ghi nào cả, vì vậy không
thể đặt lệnh x3010: BRp x0F được. Phải gọi 1 lệnh để set các cờ điều kiện dựa vào thanh
ghi R0 trước, sau đó mới kiểm tra các cờ dùng lệnh BRp. Câu lệnh ở x3010 không có ý nghĩa
thực thi, tuy nhiên có ý nghĩa set các cờ điều kiện theo thanh ghi mong muốn.
Ví d 10: So sánh hai thanh ghi R0 và R1, nếu thanh ghi R0 lớn hơn hoặc bằng R1 thì nhảy
đến lệnh ở địa chỉ x3020. Chương trình bắt đầu từ x3050.
Phân tích: để so sánh ta sẽ phải dùng phép trừ hai thanh ghi. x3050: NOT R1,R1 x3051: ADD R1,R1,#1 x3052: ADD R0,R1,R1
Phân tích: sau lệnh vừa rồi, thanh ghi kết quả R0 đó chính là hiệu của R0 và R1 trước đó, vì
vậy ta không cần phải gọi lệnh như ví dụ 9 nữa. Tiếp theo sẽ là lệnh x3053: BRzp PCoffset9.
Để tính PC offset, ta cần tính độ dời bằng cách trừ thanh ghi đích cho thanh ghi PC. Chú ý là
sau pha lấy lệnh thì PC được tăng thêm 1, như vậy PC = x3054.
Lúc này PCoffset = x3020 – x3054 = xFFCC (bỏ qua việc bị tràn số), rút gọn lại 9 bit (vì lệnh
này chỉ có 9 bit cho phần offset) là x1CC: x3053: BRzp x1CC
Một cách khác các bạn tính phép tính trên sẽ thu được PCoffset = x-34, như vậy có thể viết lệnh: x3053: BRzp x-34
Từ câu lệnh rẽ nhánh này, ta có thể sử dụng phương pháp lặp để giảm bớt khối lượng lập
trình. Có hai phương pháp để lặp, cách thứ nhất là dùng biến đếm (tương ứng với vòng lặp
for mà các bạn đã được học trước đây), cách còn lại là dùng trị canh (tương ứng với vòng lặp
while). Các bạn có thể tham khảo thêm trong giáo trình. Trong bài viết này trình bày hai ví dụ về hai cách lặp.
Ví d 11: Viết đoạn chương trình bắt đầu từ x3020 thực hiện nhân giá trị trong thanh ghi R0
với 8, sau đó lưu vào thanh ghi R1 và nhảy đến câu lệnh tại địa chỉ x3080.
Phân tích: đầu tiên ta sẽ khởi tạo thanh ghi R2 bằng 8, thanh ghi R1 bằng 0. Sau đó mỗi bước
ta cộng vào thanh ghi R1 bằng với giá trị của R0 và giảm R2 đi 1 đơn vị. Đến khi R2 vừa
bằng 0 thì nhảy đến câu lệnh ở x3080. Địa chỉ Lệnh hoặc dữ liệu Giải thích x3020 AND R1,R1,#0 Khởi tạo R1 = #0 x3021 ADD R2,R1,#8 Khởi tạo R2 = #8 x3022 ADD R1,R1,R0 x3023 ADD R2,R2,#-1 x3024 BRp x-3
Nếu R2 còn dương thì nhảy về câu lệnh ở x3022 x3025 BR x5A
Ngược lại, nhảy đến câu lệnh tại x3060
Ví d 12: Cho một chuỗi kí tự bắt đầu tại địa chỉ x3100, viết chương trình đếm số kí tự của
chuỗi đó. Cho biết dấu hiệu nhận biết chuỗi kí tự là kí tự có mã ASCII bằng 0 và không tính
kí tự này vào chiều dài của chuỗi. Đoạn chương trình viết bắt đầu tại x3020, sau khi đếm xong
thì nhảy đến địa chỉ x3080. Địa chỉ Lệnh hoặc dữ liệu Giải thích x3020 LEA R1,x7F
Tạo địa chỉ đầu R1 = x3100 x3021 AND R2,R2,#0
Khởi tạo biến đếm R2 = #0 x3022 LDR R0,R1,#0 Lấy kí tự x3023 BRz x5C
Nếu kí tự bằng 0, ngừng đếm và nhảy đến x3080 x3024 ADD R2,R2,#1
Nếu kí tự khác 0, tăng biến đếm thêm 1, tăng địa chỉ thêm x3025 ADD R1,R1,#1
1 và nhảy về lại câu lệnh lấy kí tự x3026 BR x-5
Lệnh cuối cùng là lệnh TRAP (opcode 1111). Mã lệnh này sẽ gọi các thủ tục có sẵn trong
chương trình. Có 6 mã chương trình được hỗ trợ trong phần mềm Simulator.exe của LC-3.
Trap Lệnh hợp ngữ Lệnh hợp Chức năng vector ngữ rút gọn
Đọc 1 kí tự từ bàn phím, kí tự này không hiện ra x20 TRAP x20 GETC
màn hình. Mã ASCII của kí tự vừa nhập được lưu vào thanh ghi R0. x21 TRAP x21 OUT
Xuất kí tự từ thanh ghi R0 (mã ASCII) ra màn hình.
Xuất mảng kí tự ra màn hình, địa chỉ bắt đầu của x22 TRAP x22 PUTS
mảng là thanh ghi R0. Mỗi ô nhớ tương ứng vi 1
kí t
ự. In đến khi xuất hiện kí tự bằng 0 trong mảng.
Đọc 1 kí tự từ bàn phím, kí tự này được hiện ra màn x23 TRAP x23 IN
hình. Mã ASCII của kí tự vừa nhập được lưu vào thanh ghi R0.
Xuất mảng kí tự ra màn hình, địa chỉ bắt đầu của
mảng là thanh ghi R0. Mỗi ô nhớ tương ứng với 2 x24 TRAP x24 PUTSP
kí tự. Kí tự in đầu nằm ở bit [15:8], kí tự sau nằm ở
bit [7:0]. In đến khi xuất hiện kí tự bằng 0 trong mảng. x25 TRAP x25 HALT Dừng chương trình
Ví d 13: Viết chương trình nhập 2 kí tự số (từ 0 đến 9) từ bàn phím, tính tổng 2 số và xuất ra màn hình. Địa chỉ Lệnh hoặc dữ liệu Giải thích x3000 IN Nhập kí tự thứ nhất x3001 LD R1,x13
Lấy hằng số chuyển từ mã ASCII sang số và lưu vào R1. x3002 NOT R1,R1 Chuyển thành số âm x3003 ADD R1,R1,#1 x3004 ADD R2,R0,R1
Lưu kết quả số vừa nhập vào R2, để thanh ghi R0 nhận kí tự mới x3005 IN Nhập kí tự thứ hai x3006 ADD R2,R0,R2
Cộng hai số vừa nhập với nhau. x3007 ADD R2,R2,R1
x3008 ADD R3,R2,#-10 Kiểm tra xem tổng có lớn hơn 10 hay không, nếu có thì x3009 BRn x7
nhảy đến câu lệnh x3011 x300A LD R0,xA
Xuất lần lượt hai ký tự x300B ADD R0,R0,#1 x300C OUT x300D LD R0,x7 x300E ADD R0,R0,R3 x300F OUT x3010 BR x3 Nhảy đến ô x3014 x3011 LD R0,x3 Xuất 1 kí tự. x3012 ADD R0,R0,R2 x3013 OUT x3014 HALT Dừng chương trình x3015 x0030
Hằng số chuyển từ mã ASCII sang số (x30 = #48)
2. L¿p trình hÿp ngÿ LC-3
a. Lệnh hợp ngữ trong LC-3:
Một lệnh hợp ngữ trong LC-3 bao gồm 4 thành phần:
Nhãn Mã lệnh Toán hạng ; Chú thích
Trong đó phần bắt buộc phải có là mã lệnh. Tùy vào lệnh là gì mà có thể có hoặc không có
toán hạng. Hai phần dụng để giải thích ý nghĩa của một lệnh hoặc một đoạn lệnh. Giúp cho người đọc dễ dàng
nắm bắt ý tưởng của người lập trình. Bắt buộc trước chú thích phải là dấu chấm phẩy (;).
Ví d 14: Câu lệnh
LAP ADD R1,R1,#-1 ;giam R1 xuong 1 don vi Trong đó: - LAP là nhãn của lệnh - ADD là mã lệnh
- R1,R1,#-1 là các toán hạng của lệnh tương ứng
- ;giam R1 xuong 1 don vi là chú thích về ý nghĩa của lệnh
Ví d 15: Câu lệnh IN chỉ có mã lệnh, không có các thành phần còn lại. b. Nhãn:
Nhãn là các tên tượng trưng được dùng để xác định các ô nhớ được tham khảo tới trong
chương trình. Trong hợp ngữ LC-3, một nhãn có thể được tạo từ một tới 20 ký số hay ký tự,
và bắt đầu bằng một ký tự, như LAPLAI, KETTHUC, LAP100,….
Có hai lý do cần cho việc tham khảo một vị trí trong bộ nhớ, đó là
- Ô nhớ vị trí đó chứa đích của một lệnh rẽ nhánh.
- Ô nhớ vị trí đó chứa một giá trị cần được nạp hay lưu.
Ví d 16: Giả sử rằng các cờ điều kiện đã được set theo thanh ghi R0, viết đoạn chương trình
tiếp theo kiểm tra nếu R0 lớn hơn 0 thì thực hiện cộng R1 thêm 1 đơn vị, nếu R0 bé hơn 0 thì
cộng R2 thêm 1 đơn vị, nếu R0 bằng 0 thì cộng R3 thêm 1 đơn vị, sau đó dừng chương trình. … BRp LON_HON_0 BRn BE HON 0 ADD R3,R3,#1 BR KET_THUC LON_HON_0 ADD R1,R1,#1 BR KET THUC BE_HON_0 ADD R2,R2,#1 KET_THUC HALT
Như vậy việc dùng nhãn sẽ giúp cho bộ hợp dịch tự động tính các giá trị offset cho các lệnh
có chứa giá trị này (ví dụ lệnh BR, LD, LEA, …). Người lập trình sẽ tránh được việc phải tự
tính tay các độ dời, đặc biệt là tránh việc phải tính lại độ dời khi thêm các dòng lệnh vào giữa chương trình. c. Các mã giả:
Bộ hợp dịch LC-3 là một chương trình lấy đầu vào là chuỗi ký tự biểu diễn một chương trình
được viết bằng hợp ngữ LC-3, và dịch nó ra thành một chương trình ở cấp kiến trúc tập lệnh (ISA) của LC-3.
Mã giả (pseudo-ops) giúp cho bộ dịch thực hiện nhiệm vụ này, còn được gọi bằng một tên
khác là hướng dẫn dịch (assembler directives).
Bộ hợp dịch LC-3 gồm năm mã giả: .ORIG, .FILL, .BLKW, .STRINGZ, và .END. Lưu ý tất
cả mã giả này đều có dấu chấm như là ký tự đầu tiên của nó. Mã giả Ví dụ Chức năng .ORIG .ORIG x3000
Chỉ cho bộ hợp dịch biết vị trí ô nhớ bắt đầu của
chương trình. Câu lệnh đầu tiên được dịch cũng sẽ đặt ở vị trí đó.
Như ở ví dụ, câu lệnh đầu tiên được dịch sẽ được đặt tại vị trí x3000. .FILL .FILL x1234
Yêu cầu bộ hợp dịch để dành ô nhớ tiếp theo trong
chương trình để lưu dữ liệu. Giá trị khởi tạo của ô
nhớ này là toán hạng của mã giả.
Như ở ví dụ, ô nhớ tiếp theo sẽ được khởi tạo giá trị x1234. .BLKW
MANG .BLKW x10 Yêu cầu bộ hợp dịch để dành một lượng ô nhớ bằng
với toán hạng của mã giả để lưu trữ dữ liệu.
Như ở ví dụ, 16 ô nhớ tiếp theo sẽ được để dành để
lưu dữ liệu. Nhãn của lệnh này (MANG) sẽ tương ứng
với vị trí ô nhớ đầu tiên trong khối. .STRINGZ MANG_KI_TU
Yêu cầu bộ hợp dịch khởi tạo n+1 ô nhớ, trong đó n .STRINGZ
ô ứng với chiều dài của mảng và ô cuối cùng mang
thể để làm trị canh cho các thuật toán lặp.
Như ở ví dụ, bộ nhớ được yêu cầu để dành mảng có
13 ô nhớ. Nhãn của lệnh tương ứng với vị trí ô nhớ đầu tiên. .END
Báo cho bộ hợp dịch biết vị trí cuối cùng của chương
trình. Tất cả các lệnh sau mã này sẽ không được dịch.
Ví d 17: Viết chương trình hợp ngữ hoàn chỉnh thực hiện các yêu cầu sau:
- Nhập lần lượt hai số (từ 0 đến 9) từ bàn phím.
- Tính tổng của hai số này và in ra màn hình theo cú pháp: Trong đó XX tương ứng với kết quả.
- Lưu kết quả này vào 3 ô nhớ tại địa chỉ x4000, x4001, x4002 theo thứ tự: số nhập thứ
nhất, số nhập thứ hai, tổng của 2 số. .ORIG x3000 IN ;nhập kí tự thứ nhất LD R1,ASCII_0 ;chuyển mã ascii thành số NOT R1,R1 ADD R1,R1,#1 ADD R2,R0,R1 ;lưu giá trị số vào R2 IN ADD R3,R0,R1 ;và R3 ADD R4,R2,R3 ;tổng của 2 số LD
R0,DIA_CHI_LUU ;lấy địa chỉ lưu dữ liệu STR R2,R0,#0 ;lưu dưới dạng base + offset STR R3,R0,#1 STR R4,R0,#2 LEA R0,STROUT ;lấy ô nhớ đia chỉ của chuối thông báo PUTS ;xuất chuỗi ra trước, xuất kết quả sau LD R1,ASCII_0 ADD R5,R4,#-10 ;kiểm tra tổng có bao nhiêu chữ số BRzp XUAT_2_CHU_SO ADD R0,R4,R1 ;xuất 1 chữ số OUT BR KET_THUC XUAT_2_CHU_SO ADD R0,R1,#1
;chữ số đầu tiên chắc chắn là 1 OUT ADD R0,R5,R1 ;sau khi trừ 10 thì R5 chứa chữ số hàng đơn vị OUT KET_THUC HALT ASCII_0 .FILL #48 DIA CHI LUU .FILL x4000 STROUT .STRINGZ .END
d. Lập trình sử dụng LC3Edit.exe và mô phỏng dùng Simulate.exe
Sử dụng phần mềm LC3Edit.exe để lập trình lại ví dụ vừa rồi.
Do chương trình được viết bằng hợp ngữ, phải lưu chương trình với tên file có đuôi là <.asm= và phải bấm vào nút
để biên dịch. Nếu không có lỗi, ta nhận được kết quả:
Sau đó, mở phần mêm Simulate.exe để chạy thử.
Mở File → Load Program (Ctrl + L) hoặc nút
, chọn file object vừa được LC3Edit biên
dịch, ta thu được kết quả như hình dưới. Bấm vào nút
để chạy chương trình. Sau khi chạy
xong, để chạy lại một lần nữa ta phải Load Program lại, hoặc đơn giản hơn có thể chọn vào
File → Reload Program. Ngoài ra có thể chọn chức năng nhớ bất kì.
Một kết quả ví dụ khi tổng có 2 chữ số:
Một kết quả ví dụ khi tổng có 1 chữ số: e. Một số ví dụ khác:
Trong phần này sẽ trình bày một số ví dụ đơn giản về lập trình hợp ngữ LC-3.
Ví d 18: Viết chương trình thực hiện nhập 2 số (từ 0 đến 9) từ bàn phím, tính hiệu của 2 số này và in ra màn hình.
Phân tích: Ta thấy rằng hiệu của 2 số 1 chữ số chắc chắn cũng chỉ có 1 chữ số. Tuy nhiên hiệu
này có thể là số âm, vì vậy cần phải dùng câu lệnh rẽ nhánh. Khi gặp trường hợp số âm, ta in
ra dấu <-<, sau đó chuyển kết quả thành số dương (bù 2) và in ra màn hình. .ORIG x3000 IN ADD R1,R0,#0 ;copy dữ liệu từ R0 sang R1, chừa lại vị trí R0 để nhập kí tự tiếp theo IN NOT R0,R0 ADD R0,R0,#1 ADD R1,R1,R0 ;R1 := R1-R0 BRzp IN_CHU_SO LD
R0,MINUS_SIGN ;nếu là số âm, chuyển thành số dương và in dấu <-< OUT NOT R1,R1 ADD R1,R1,#1 IN_CHU_SO LD R0,ASCII_0 ADD R0,R0,R1 OUT HALT MINUS_SIGN .FILL #45 ;=-< ASCII_0 .FILL #48 ;=0= .END
Ví d 19: Viết chương trình thực hiện nhập 2 số (từ 0 đến 9) từ bàn phím, tính tích hai số này và in ra màn hình.
Phân tích: Có 2 thuật toán chính cần phải thực hiện trong bài này:
- Sử dụng lặp biết trước số lần để tính tích của hai số
- Sử dụng lặp không biết trước số lần để tách một số bất kì thành 2 chữ số hàng chục và hàng đơn vị .ORIG x3000 IN LD R1,ASCII_0M ;lấy hằng số chuyển từ mã ASCII sang số ADD R2,R0,R1 ;copy dữ liệu số vừa nhập R2 IN ADD R3,R0,R1 AND R4,R4,#0 ;tính tích R2 x R3 LAP ADD R2,R2,#-1 BRn TACH SO ADD R4,R4,R3 BR LAP TACH_SO AND R2,R2,#0 ;tách chữ số hàng chục và hàng đơn vị LAP2 ADD R4,R4,#-10 BRn TIEP ADD R2,R2,#1 ;R2 là chữ số hàng chục BR LAP2 TIEP ADD R3,R4,#10 ;R3 là chữ số hàng đơn vị LD R1,ASCII_0 ADD R2,R2,#0 ;kiểm tra R2 bằng 0 thì bỏ qua, không in BRz XUAT DON VI ADD R0,R2,R1 OUT XUAT DON VI ADD R0,R3,R1 OUT HALT ASCII_0 .FILL #48 ;=0= ASCII 0M .FILL #-48 .END
Ví d 20: So sánh hai số 1 chữ số được nhập từ bàn phím (lần lượt nhập vào là a và b)
- Nếu a > b thì in ra màn hình: - Nếu a < b thì in ra màn hình: - Nếu a = b thì in ra màn hình Phân tích: Bài này không quá khó, chỉ cần lấy hiệu hai kí tự vừa được nhận vào và rẽ nhánh hai lần. .ORIG x3000 IN ADD R1,R0,#0 ;copy dữ liệu từ R0 sang R1 IN NOT R0,R0 ADD R0,R0,#1 ADD R1,R1,R0 ;R1 := R1-R0 BRn BE_HON BRp LON HON LEA R0,STR_BANG ;2 so bang nhau BR IN_CHUOI BE_HON LEA R0,STR_BE BR IN CHUOI LON_HON LEA R0,STR_LON IN_CHUOI PUTS HALT STR_BE .STRINGZ STR_LON .STRINGZ STR BANG .STRINGZ .END
Ví d 21: Mở rộng ví dụ ở trên, in ra màn hình giá trị lớn nhất, giá trị bé nhất của 3 số được nhập từ bàn phím.
Phân tích: Sử dụng phép lặp biết trước số lần, có thể mở rộng thay số 3 bởi số lượng bất kì.
Vì các phép so sánh là phép trừ nên có thể dùng trực tiếp mà không cần phải chuyển từ mã ASCII sang số.
Chức năng của các biến trong chương trình:
- R1: lưu số lần lặp còn lại
- R2: lưu giá trị nhỏ nhất
- R3: lưu giá trị lớn nhất .ORIG x3000 LD
R1,SO_LAN_LAP ;số lần lặp LD R2,INIT_MIN
;khởi tạo giá trị nhỏ nhất LD R3,INIT_MAX
;khởi tạo giá trị lớn nhất LAP IN NOT R4,R0 ;chuyển R0 thành số ầm để tính hiệu ADD R4,R4,#1 ADD R5,R2,R4 ;so sánh với giá trị nhỏ nhất BRnz TIEP_TUC_1 ADD R2,R0,#0 TIEP TUC 1 ADD R5,R3,R4 BRzp TIEP_TUC_2 ADD R3,R0,#0 TIEP_TUC_2 ADD R1,R1,#-1 ;giảm R1 đi 1 đơn vị, nếu bằng 0 thì bắt đầu in dữ liệu BRp LAP LEA R0,STR MIN ;in min và max PUTS ADD R0,R2,#0 OUT LEA R0,STR MAX PUTS ADD R0,R3,#0 OUT HALT SO_LAN_LAP .FILL #3 INIT_MIN .FILL #57 INIT MAX .FILL #48 STR_MIN .STRINGZ STR_MAX
.STRINGZ <\nSo lon nhat la: < .END
Ví d 22: Nhập một chuỗi các số có một chữ số từ bàn phím, kết thúc khi nhập vào ký tự #.
In ra màn hình tổng của dãy số vừa được nhập (giả sử rằng tổng của dãy này nhỏ hơn 100).
Lưu các số vừa được nhập vào vào bộ nhớ từ địa chỉ x4000, kết thúc bằng giá trị <#=.
Cho biết mã ASCII của kí tự <#= là x23. .ORIG x3000 LD R1,ASCII_#M LD R2,ASCII_0M LD R3,DIA CHI DAU AND R4,R4,#0 ;tổng của dãy LAP IN ADD R5,R0,R1 BRz NGUNG LAP ADD R5,R0,R2 STR R5,R3,#0 ;lưu giá trị vào bộ nhớ ADD R3,R3,#1 ;tăng địa chỉ ô nhớ lên 1 ADD R4,R4,R5 ;tính tổng BR LAP NGUNG_LAP STR R0,R3,#0 ;lưu kí tự # vào ô nhớ, không cần thiết
phải tăng địa chỉ nữa LEA R0,STR OUT PUTS AND R2,R2,#0 ;tách chữ số hàng chục và hàng đơn vị LAP2 ADD R4,R4,#-10 BRn TIEP ADD R2,R2,#1 ;R2 là chữ số hàng chục BR LAP2 TIEP ADD R3,R4,#10 ;R3 là chữ số hàng đơn vị LD R1,ASCII 0 ADD R2,R2,#0 ;kiểm tra R2 bằng 0 thì bỏ qua, không in BRz XUAT_DON_VI ADD R0,R2,R1 OUT XUAT_DON_VI ADD R0,R3,R1 OUT HALT ASCII_0 .FILL #48 ;=0= ASCII_0M .FILL #-48 ASCII #M .FILL x-23 ;=#= DIA_CHI_DAU .FILL x4000 STR_OUT .STRINGZ .END - HT -