You are on page 1of 10

BÁO CÁO TH CẤU TRÚC MÁY TÍNH

BÀI 5: GIAO TIẾP VỚI CÁC THIẾT BỊ NGOẠI VI


HEX - KEY

Mssv Họ và tên

18200103 Nguyễn Phùng Hiếu

Đề bài: Viết chương trình assembly đọc ký tự N từ JTAG UART


và hiển thị ký tự đó ở dạng hệ cơ số 10 tương ứng trên HEX2-
HEX0 và chương trình sẽ kết thúc khi gặp ký tự 'q'.
- N là một trong các ký tự từ 'a' đến 'k' theo bảng chữ cái.
- Ví dụ: N = 'a', thì HEX2-HEX0 hiển thị số 97.
Lưu ý: viết hàm con xử lý hiển thị trên HEX2-HEX0.
1. Code Assembly
.text
.equ HEX3_HEX0, 0x10000020
.global _start
_start:
/* set up stack pointer */
movia sp, 0x07ffffff - 3
movia r7, SEVEN_SEG_DECODE_TABLE
movia r6, 0x10001000
movi r11,0x99
movi r12,0x71
/* read and echo characters */
GET_JTAG:
ldwio r4, 0(r6)
andi r8, r4, 0x8000
beq r8, r0, GET_JTAG
andi r5, r4, 0x00ff
call PUT_JTAG
beq r5, r12, LOOP
addi r5, r5,0x36
bgt r5, r11, BBIG
call HEX_DISPLAY
br GET_JTAG
BBIG:
addi r5, r5,0x66
call HEX_DISPLAY
br GET_JTAG
.global HEX_DISPLAY
HEX_DISPLAY:
/* save any modified registers: r2 r3 r5 r9 r10 r15 r16 r17*/
subi sp, sp, 28
stw r2, 0(sp)
stw r3, 4(sp)
stw r5, 8(sp)
stw r9, 12(sp)
stw r10, 16(sp)
stw r15, 20(sp)
stw r16, 24(sp)
stw r17, 28(sp)

andi r2, r5, 0xF


andi r3, r5, 0xF0
andi r10, r5,0xF00
srli r3, r3, 0x4
srli r10, r10, 0x8

movia r9, HEX_SEGMENTS


add r15, r7, r2
ldb r16, 0(r15)
stb r16, 0(r9)
addi r9, r9, 1

add r15, r7, r3


ldb r16, 0(r15)
stb r16, 0(r9)
addi r9, r9, 1

add r15, r7, r10


ldb r16, 0(r15)
stb r16, 0(r9)

movia r9, HEX_SEGMENTS


ldw r16, 0(r9)
movia r17, HEX3_HEX0
stwio r16, 0(r17)

/* restore registers */
ldw r2, 0(sp)
ldw r3, 4(sp)
ldw r5, 8(sp)
ldw r9, 12(sp)
ldw r10, 16(sp)
ldw r15, 20(sp)
ldw r16, 24(sp)
ldw r17, 28(sp)
addi sp, sp, 28
ret

.global PUT_JTAG
PUT_JTAG:
/* save any modified registers */
subi sp, sp, 4
stw r4, 0(sp)

ldwio r4, 4(r6)


andhi r4, r4, 0xffff
beq r4, r0, END_PUT
stwio r5, 0(r6)

END_PUT:
/* restore registers */
ldw r4, 0(sp)
addi sp, sp, 4
ret
LOOP:
br LOOP
.data
.skip 3
N: .byte 16
SEVEN_SEG_DECODE_TABLE:
.byte 0b00111111, 0b00000110, 0b01011011, 0b01001111
.byte 0b01100110, 0b01101101, 0b01111101, 0b00000111
.byte 0b01111111, 0b01100111, 0b01110111, 0b01111100
.byte 0b00111001, 0b01011110, 0b01111001, 0b01110001
HEX_SEGMENTS: .fill 1, 4, 0

.end
2. Giải thích tổng quan chương trình code:

- đọc ký tự N từ JTAG UART và hiển thị ký tự đó ở dạng hệ cơ số 10 tương ứng


trên HEX2-HEX0 thì ta chuyển từ HEX sang DEC bằng cách cộng thêm cho
0x36 để thành thập phân sau đó tách lấy hàng trăm, chục, đơn vị để hiển thị
từng LED
- để hiển thị từng LED, and với mask tương ứng rồi cho hiển thị lần lượt qua các
LED 7 đoạn.
3. Giải thích chi tiết chương trình code
#Gán địa chỉ cho nhãn
.equ HEX3_HEX0, 0x10000020
#Gán địa chỉ của con trỏ stack, JTAG UART và led 7 đoạn vào biến, gán giá trị cho
thanh ghi r11 và r12
_start:
/* set up stack pointer */
# starts from largest memory address 41:32
movia sp, 0x07ffffff – 3
# JTAG UART base address
movia r6, 0x10001000
#r7 = addr(SEVEN_SEG_DECODE_TABLE[0])
movia r7, SEVEN_SEG_DECODE_TABLE
# giá trị so sánh: 0x36 + 0x66 để so sánh >=ký tự 'd'
movi r11,0x99
# kí tự kết thúc chương trình 'q'
movi r12,0x71
#Đọc dữ liệu từ JTAG UART, gọi hàm echo để hiển thị lên màn hình, kiểm tra xem
ký tự có phải là ‘q’ không và xử lý ký tự vừa nhập vào để hiển thị lên led 7 đoạn
GET_JTAG:
/* read and echo characters */
# read the JTAG UART data register
ldwio r4, 0(r6)
# check if there is new data
andi r8, r4, 0x8000
# if no data, wait
beq r8, r0, GET_JTAG
# the data is in the least significant byte
andi r5, r4, 0x00ff
# echo character
call PUT_JTAG
# thoát chương trình khi kí tự nhập vào là 'q'
beq r5, r12, LOOP
#hex to decimal 0x36(< 64), 0x99(>= 64)
# cộng thêm 0x36 cho ký tự mới nhập
addi r5, r5,0x36
#kiểm tra nếu ký tự >= ký tự 'd' thì nhảy vào BBIG
bgt r5, r11, BBIG
#nếu < ký tự 'd' thì gọi hàm HEX_DISPLAY
call HEX_DISPLAY
#hiển thị xong thì chờ ký tự mới
br GET_JTAG
BBIG:

# hex to decimal 0x36(< 64), 0x99(>= 64)


#ký tự >= ký tự 'd' thì cộng thêm 0x66
addi r5, r5,0x66
#gọi hàm HEX_DISPLAY
call HEX_DISPLAY
#hiển thị xong thì chờ ký tự mới
br GET_JTAG

#Lưu dữ liệu các thanh ghi sẽ bị sửa đổi dữ kiện


.global HEX_DISPLAY
HEX_DISPLAY:
/*#save
reserve
anyspace on the
modified stack r2 r3 r5 r9 r10 r15 r16 r17*/
registers:
subi sp, sp, 28
# save register
stw r2, 0(sp)
# save register
stw r3, 4(sp)
# save register
stw r5, 8(sp)
# save register
stw r9, 12(sp)
# save register
stw r10, 16(sp)
# save register
stw r15, 20(sp)
# save register
stw r16, 24(sp)
# save register
stw r17, 28(sp)

#Tách lấy hàng trăm, chục, đơn vị ở thanh ghi r5 lưu vào r2 r3 r10 để hiển thị
LED 7 đoạn
andi r2, r5, 0xF
andi r3, r5, 0xF0
andi r10, r5,0xF00
srli r3, r3, 0x4
srli r10, r10, 0x8
#Hiển thị lên LED 7 đoạn
movia r9, HEX_SEGMENTS
add r15, r7, r2
ldb r16, 0(r15)
stb r16, 0(r9)
addi r9, r9, 1

add r15, r7, r3


ldb r16, 0(r15)
stb r16, 0(r9)
addi r9, r9, 1

add r15, r7, r10


ldb r16, 0(r15)
stb r16, 0(r9)

movia r9, HEX_SEGMENTS


ldw r16, 0(r9)
movia r17, HEX3_HEX0
stwio r16, 0(r17)

#Trả lại giá trị ban đầu cho các thanh ghi lưu trong stack sau đó return
/* restore registers */
ldw r2, 0(sp)
ldw r3, 4(sp)
ldw r5, 8(sp)
ldw r9, 12(sp)
ldw r10, 16(sp)
ldw r15, 20(sp)
ldw r16, 24(sp)
ldw r17, 28(sp)
# reserve space on the stack
addi sp, sp, 28
ret
#Hàm con gửi dữ liệu lên màn hình
.global PUT_JTAG
PUT_JTAG:
/* save any modified registers */

# reserve space on the stack


subi sp, sp, 4
# save register
stw r4, 0(sp)
# read the JTAG UART control register
ldwio r4, 4(r6)
# check for write space# b b b b
andhi r4, r4, 0xffff

# if no space, ignore the character #wspace: số lượng space sẵn có


beq r4, r0, END_PUT
# send the character
stwio r5, 0(r6)
END_PUT:
/* restore registers */

ldw r4, 0(sp)


addi sp, sp, 4
ret
#Thoát chương trình bằng cách lặp vô hạn
LOOP:
#dừng chương trình bằng cách lặp vô hạn
br LOOP
#Bảng mã LED 7 đoạn
.data
# bỏ qua 3-Byte
.skip 3
# N = 16
N: .byte 16
SEVEN_SEG_DECODE_TABLE:
.byte 0b00111111, 0b00000110, 0b01011011, 0b01001111
.byte 0b01100110, 0b01101101, 0b01111101, 0b00000111
.byte 0b01111111, 0b01100111, 0b01110111, 0b01111100
.byte 0b00111001, 0b01011110, 0b01111001, 0b01110001
# tạo 1 ô nhớ, size = 4-bytes, giá trị 0
HEX_SEGMENTS: .fill 1, 4, 0
.end

Mô phỏng chương trình:

You might also like