LẬP TRÌNH VI ĐIỀU KHIỂN STM32L152
(Sách Embedded Systems with ARM Cortex-M Microcontrollers
in Assembly Language and C (Third Edition) – Dr Yifeng Zhu )
Đại Học Bách Khoa Đà Nẵng
BÀI TẬP CHƯƠNG 6 SÁCH (Có code đính kèm)
6.1. Translate_Code
Đề : dịch đoạn chương trình asm sau sang ngôn ngữ lập trình C
MOV r2, #1
MOV r1, #1
loop
CMP r1, r0
BGT done
MUL r2, r1, r2
ADD r1, r1, #1
B
done
loop
MOV r0, r2
Code:
int main(void){
int result, n = 3, i;
result = 1;
for(i = 1; i <= n ; i++){
result = result *i;
}
n = result;
while(1);
}
6.3. Mean –Trung bình cộng
Đề : Define an array with 10 unsigned integers in asemply code and write an
assemply program that calculated the mean of these 10 integers (truncating the
result to an integer)
Xác định một mảng gồm 10 số nguyên không dấu trong code asemply va viết một
chương trình asm để tính trung bình cộng của 10 số đó (kết quả là một số nguyên)
Code:
INCLUDE stm32l1xx_constants.s
; Load Constant Definitions
INCLUDE stm32l1xx_tim_constants.s ; TIM Constants
AREA
main, CODE, READONLY
EXPORT
__main
; make __main visible to linker
ENTRY
__main
PROC
; r0 = i, r1 = sum, r2 = =array, r3 = n- kich thuoc mang, r4 = =n, r5 = array[i]
MOV r0, #0
;i=0
MOV r1 ,#0
; sum = 0
LDR r2, =array
; r2 = &array[0] - r2 chua dia chi tham chieu cua bien array
LDR r4, =n
; r4 = &n
LDR r3, [r4]
; r3 = n = 10
loop
BEQ endloop
CMP r0, r3
; so sanh i voi kich thuoc mang
; i = 10 thi vao endloop
LDR r5, [r2]
; nap array[i] vao r5
ADD r1, r5
; sum += array[i]
ADD r0, #1
; i += 1
ADD r2, #4
; i += 1 r2 chua dia chi tiep theo cua array
B
loop
endloop
UDIV r5, r1, r3
; mean = sum/n
LDR r4, =mean
STR r5, [r4]
stop
; luu r5 vao bien mean trong bo nho
B
stop
; dead loop & program hangs here;
ENDP
ALIGN
AREA
myData, DATA, READWRITE
ALIGN
array
DCD
n
DCD 10
mean
DCD 0
1, 2, 3, 4, 5, 6, 7, 8, 9, 10
; moi phan tu 32 bit
END
6.4. TheSumCube –Tổng lập phương
Đề : Xác định một mảng 10 số nguyên không dấu ai ( 0 <= i <= 9 ) bàng code
assemply, viết một chương trình asm tính tổng lập phương của 10 số không dấu đó
Mảng này được xác định trong bộ nhớ dữ liệu sau:
AREA myData, DATA
array DCD 2, 4, 7, 3, 1, 2, 10, 11, 5, 13
array DCD 10
Code:
INCLUDE stm32l1xx_constants.s
; Load Constant Definitions
INCLUDE stm32l1xx_tim_constants.s ; TIM Constants
AREA
main, CODE, READONLY
EXPORT
__main
; make __main visible to linker
ENTRY
__main
PROC
; r0 = array[i]^3 ,r1 = result, r2 = i, r3 = size, r4 = &array[0] , r5 = array[i], ket qua =
5104
LDR
r3, =size
; r3 chua dia chi tham chieu cua size
LDR
r3, [r3]
; arraySize = 10
SUB
r3, r3, #1
; arraySize -1 ; cho i chay tu 0 den 9
LDR
r4, =array
; r4 = &array[0]
MOV
r1, #0
; sum = 0
MOV
r2, #0
;i=0
loop
CMP
BGT
stop
; vao stop neu i > 9
LDR
r5, [r4, r2, LSL #2]
; array[i]; dich trai r2 2 bit = 4*i +&array[0]
MUL
r0, r5, r5
; r0 = array[i] ^2
MLA
r1, r0, r5, r1
; result = sum + array[i] ^3 - phep cong don
LDR
r6, =cube
r2, r3
; so sanh i voi 9
STR
r1, [r6]
; luu ket qua vao bo nho
ADD
r2, r2, #1
;i=i+1
B
loop
stop
B
stop
; dead loop & program hangs here
ENDP
ALIGN
AREA
myData, DATA, READWRITE
ALIGN
array
DCD 2, 4, 7, 3, 1, 2, 10, 11, 5, 13
; khai bao mang 10 so
size
DCD 10
; kich thuoc mang
cube
DCD
0
END
6.5. UpperCase- Chuyển thành chữ hoa
Đề: Viết chương trình asm chuyển từ ký tự thường sang ký tự hoa
Code:
INCLUDE stm32l1xx_constants.s
; Load Constant Definitions
INCLUDE stm32l1xx_tim_constants.s ; TIM Constants
AREA
main, CODE, READONLY
EXPORT
__main
; make __main visible to linker
ENTRY
__main
PROC
; r0 = giatri, r1 = =str
; signed number
LDR r1, =str
; r1 = &str
loop
LDRB r0, [r1]
; nap 1 byte
CBZ
r0, endloop
; dung neu str[i = 0
CMP
r0, #'a'
; so sanh str[i voi voi a
BLO
next
; vao next neu str[i < a
CMP
r0, #'z'
;
BHI
next
; vao next neu str[i > z
SUB
r0, #32
; chuyen doi tu ky tu thuong sang ky tu hoa
STRB r0, [r1]
next
ADD
B
loop
; luu gia tri r0 1 byte vao bo nho
r1, #1
; &str += 1
endloop
stop
B
stop
; dead loop & program hangs here
ENDP
ALIGN
AREA
myData, DATA, READWRITE
ALIGN
str
END
DCB
"Arm Cortex-M3", 0
; mang ky tu
6.6. TheKineticEnergy- E =mC^2
Đề: Viết một chương trình asm tính năng lượng (E) , E = MC2, khi mà khối lượng
(M) là 15 kg và được lưu trong r0, C là tốc độ ánh sáng (299,792,458 m/s), và được
chứa trong r1. Kết quả E lưu trong thanh ghi 32 bit r2.
Code:
INCLUDE stm32l1xx_constants.s
; Load Constant Definitions
INCLUDE stm32l1xx_tim_constants.s ; TIM Constants
AREA
main, CODE, READONLY
EXPORT
__main
; make __main visible to linker
ENTRY
__main
PROC
; r0 = m, r1 = C = 299792458, r2 =
LDR
r2, =result
LDR
r0, =15
; khoi luong m = 15 kg
LDR
r1, =299792458
; C - 299792458 m/s
MUL
r3, r1, r1
; C^2
MUL
r3, r0, r3
; E = mC^2
STR
r3, [r2]
; luu gia tri vao bo nho
stop
ENDP
ALIGN
B
stop
; dead loop & program hangs here
AREA
myData, DATA, READWRITE
ALIGN
result
DCD
0
END
6.7. Expresion
Đề : Viết một chương trình asm tính giá trị của biểu thức sau: 7x2 + 9xy + 3x/y +
11x + 13y + 5, với các biến số x, y là số nguyên không dấu x = 4, y = 2.
Code:
INCLUDE stm32l1xx_constants.s
; Load Constant Definitions
INCLUDE stm32l1xx_tim_constants.s ; TIM Constants
AREA
main, CODE, READONLY
EXPORT
__main
; make __main visible to linker
ENTRY
__main
PROC
; result = 265
MOV r1, #4
;x=4
MOV
r2, #2
;y=2
MOV
r0, #5
; result = 5
MOV
r3, #7
; r3 = 7
MOV
r4, #9
; r4 = 9
MOV
r5, #3
; r4 = 3
MOV
r6, #11
; r6 = 11
MOV
r7, #13
; r7 = 13
MUL
r8, r1, r1
; r9 = ^2 = 28
MLA
r0, r8, r3, r0
; result = 7x^2 + 5
MUL
r4, r4, r1
; r4 = 9x
MLA
r0, r4, r2, r0
; result = 9xy + 7x^2 + 5
UDIV
r8, r1, r2
; r8 = x/y
MLA
r0, r5, r8, r0
; result = 3x/y + 9xy + 7x^2 + 5
MLA
r0, r6, r1, r0
; result = 11x + 3x/y + 9xy + 7x^2 + 5
MLA
r0, r7, r2, r0
; result = 13y + 11x + 3x/y + 9xy + 7x^2 + 5
LDR
r9, =expresion
STR
r0, [r9]
stop
B
; result
stop
; dead loop & program hangs here
ENDP
ALIGN
AREA
myData, DATA, READWRITE
ALIGN
expresion
DCD 0
END
6.8. QuadraticEquation –Phương trình bậc hai
Đề : Kiểm tra nghiệm số phức trong lời giải của phương trình bậc hai sau :
ax2 + bx + c = 0
Lời giải có nghiệm phức nếu b2 - 4ac nhỏ hơn 0 và là nghiệm thực với những
trường hợp còn lại. Giả sử a, b, c là những số nguyên có dấu và được lưu lần lượt
rong các thanh ghi r0, r1, r2. Viết một chương trình asm thiết lập thanh ghi r3 lên 1
nếu kết quả là nghiemj phức và 0 với trường hợp còn lại.
Code:
INCLUDE stm32l1xx_constants.s
; Load Constant Definitions
INCLUDE stm32l1xx_tim_constants.s ; TIM Constants
AREA
quadraticEquation, CODE, READONLY
EXPORT
__main
; make __main visible to linker
ENTRY
__main
PROC
; r0 = a , r1 = b, r2 = c, r3 = flag, r4 = 4ac, r5 = b^2 ; so co dau
MOV
r0, #5
;a=5
MOV
r1, #2
;b=2
MOV
r2, #2
;c=2
MOV
r4, #4
; 4 trong 4ac
MUL
r4, r0, r4
; 4a
MUL
r4, r2, r4
; 4ac
MUL
r5, r1, r1
; b^2
SUB
r5, r5, r4
; delta = b^2 - 4ac
LDR
r6, =delta
STR
r5, [r6]
CMP
r5, #0
; so sanh delta voi 0
MOVGE
r3, #2
BGE
stop
MOV
r3, #1
; delta < 0 r3 flag set 1 - hay complex roots - nghiem phuc
stop
B
stop
; delta >= 0 flag set 0 - hay real roots - nghiem thuc
; dead loop & program hangs here
ENDP
ALIGN
AREA myData, DATA, READWRITE
ALIGN
delta
DCD
0
END
6.9. SoSanhVoiZero
Đề : Viết một chương trình asm tính hàm sau:
f(x) = -1 nếu (x <0)
f(x) = 0 nếu (x = 0)
f(x) = 1 nếu (x > 0)
Code:
INCLUDE stm32l1xx_constants.s
; Load Constant Definitions
INCLUDE stm32l1xx_tim_constants.s ; TIM Constants
AREA
main, CODE, READONLY
EXPORT
ENTRY
__main
; make __main visible to linker
__main
PROC
; r0 = x , r1 = f(x)
MOV r0, #-10
CMP r0, #0
MOVLT
r1, #-1
BLT stop
MOVGT
r1, #1
BGT stop
MOVEQ
r1, #0
BEQ
stop
stop
B
stop
; dead loop & program hangs here
ENDP
ALIGN
AREA myData, DATA, READWRITE
ALIGN
;x
DCD
10
; bien x
END
6.10. CostFunction
Đề : Viết một chương trình asm tính giá trị của hàm sau. Giả sử số không dấu x là
được lưu trữ trong thanh ghi r0 và kết ủa f(x) được lưu trữ trong thanh ghi r1.
cost (x) = 9x nếu x <=10
cost (x) = 8x nếu x >10 và x <= 100
cost (x) = 7x nếu x > 100 và x <= 1000
cost (x) = 6x nếu x > 1000
Code:
INCLUDE stm32l1xx_constants.s
; Load Constant Definitions
INCLUDE stm32l1xx_tim_constants.s ; TIM Constants
AREA
main, CODE, READONLY
EXPORT
__main
; make __main visible to linker
ENTRY
__main
MOV
PROC
r0, #5
;x=5
CMP r0, #10
; so sanh x voi 10
MOVLE
; x <= 10 thi r1 = 9
r1, #9
BLE exit
; nhay vao exit
CMP r0, #100
MOVLE
r1, #8
BLE exit
CMP r0, #1000
MOVLE
r1, #7
BLE exit
; truong hop con lai x > 1000
MOV r1, #6
exit
MUL r1, r1, r0
LDR
r2, =result
STR
r1, [r2]
; cost(x) = r1*x
stop
B
stop
; dead loop & program hangs here
ENDP
ALIGN
AREA
myData, DATA, READWRITE
ALIGN
result
DCD 0
END
6.11. MinNumber
Đề : Dịch chương trình C sau thành chương trình assemply. Chương trình C tìm
kiếm giá trị nhỏ nhất trong 3 số có dấu. Giả sử a, b và c là được lưu trữ trong thanh
ghi r0, r1 và r3. Kết quả nhỏ nhất được lưu trữ trong thanh ghi r4.
Code:
INCLUDE stm32l1xx_constants.s
; Load Constant Definitions
INCLUDE stm32l1xx_tim_constants.s ; TIM Constants
AREA
main, CODE, READONLY
EXPORT
__main
; make __main visible to linker
ENTRY
__main
PROC
; a = r0, b = r1, c = r3, min = r4
; so co dau
LDR
r2, =min
MOVS
r0, #16
; a = 16
MOVS
r1, #14
; b = 14
MOVS
r3, #8
;c=2
CMP r0, r1
; kiem tra a < b
BGE elseif
CMP r0, r3
; kiem tra a < c
BGE elseif
MOV r4, r0
; min = a
STR
r4, [r2]
B
stop
elseif
CMP r1,r0
; kiem tra b < a
BGE
else
; dung neu b >= a
CMP
r1,r3
; kiem tra b < c
BGE
else
; dung neu b >= c
MOVS
r4, r1
; min = b
STR
r4, [r2]
B
stop
else
MOVS
STR
r4, [r2]
stop
B
program hangs here
; luu gia tri min vao bo nho
r4, r3
; min = c
stop
ENDP
ALIGN
AREA
myData, DATA, READWRITE
; dead loop &
ALIGN
min
DCD 0
END
6.12. CompareDate
Đề : Giả sử hai ngày được lưu trữ trong bộ nhớ như sau . Viết chương trình asm so
sánh hai ngày, nếu ngày 1 trước ngày 2, thiết lập thanh ghi r0 lên 1, trường hợp còn
lại thì thiết lập r0 là -1.
AREA, myData, DATA
date1 DCD
12, 31, 2014
; month, day, year
date2 DCD
01, 20, 2013
; month, day, year
Code:
INCLUDE stm32l1xx_constants.s
; Load Constant Definitions
INCLUDE stm32l1xx_tim_constants.s ; TIM Constants
AREA dateCompare, CODE, READONLY
EXPORT
linker
__main
; make __main visible to
ENTRY
__main
PROC
; Ngay 1 truoc ngay 2 thi set thanh ghi r0 len 1 va set r0 -1 voi nhung truong hop khac
LDR
r1, =date1
LDR
r2, =date2
; &date2[0]
; so sanh nam truoc
LDR
r3, [r1, #8]
; nam 1
LDR
r4, [r2, #8]
; nam 2
CMP
r3, r4
MOVLO
r0, #1
Lower - nam 1 truoc nam 2 thi set r0 len 1
BLO
stop
MOVHI
Higher
BHI
; LO = unsigned on
r0, #-1
; HI = unsigned on
stop
; So sanh thang
LDR
r3, [r1]
; thang 1
LDR
r4, [r2]
; thang 2
CMP
r3, r4
MOVLO
2 thi set r0 len 1
BLO
; thang 1 truoc thang
r0, #-1
; con sau thi set r0
stop
MOVHI
len -1
BHI
r0, #1
stop
; So sanh ngay
LDR
r3, [r1, #4]
; ngay 1
LDR
r4, [r2, #4]
; ngay 2
CMP
r3, r4
MOVLO
2 thi set r0 len 1
BLO
; ngay 1 truoc ngay
r0, #-1
; con sau thi set r0
stop
MOVHI
len -1
BHI
r0, #1
stop
stop
B
stop
; dead loop & program hangs here
ENDP
ALIGN
AREA
myData, DATA, READWRITE
ALIGN
date1
DCD
; month, date, year 1
12, 31, 2014
date2
DCD
; month, date, year 2
01, 20, 2013
END
6.13. TongBinhPhuong
Đề : Viết chương trình asm tính tổng của biểu thức sau. Biến n được lưu trữ trong
thanh ghi r0, và tổng bình phương thì được lưu trữ trong thanh ghi r1.
𝑛
sum = ∑𝑖=1 12 + 22 + 32 + ⋯ 𝑛2
Code:
INCLUDE stm32l1xx_constants.s
; Load Constant Definitions
INCLUDE stm32l1xx_tim_constants.s ; TIM Constants
AREA
main, CODE, READONLY
EXPORT
__main
; make __main visible to linker
ENTRY
__main
PROC
MOV r0, #4
;n=4
MOV r1, #0
; result = 0
MOV r2, #1
; i=1
loop
CMP r2, r0
; so sanh i voi n
BGT stop
; re nhanh neu lon hon
MLA
r1, r2, r2, r1
LDR
r3, =sum
STR
r1, [r3]
ADD
r2, r2, #1
B
loop
stop
; result = i*i + result
; i = i+1
B
stop
; dead loop & program hangs here
ENDP
ALIGN
AREA
myData, DATA, READWRITE
ALIGN
sum
DCD
0
END
6.14. Factorial
Đề : Viết chương trình asm tính tổng giai thừa của một số nguyên không âm . Giả sử
n được cho bởi thanh ghi r0 và kết quả được lưu trong thanh ghi r1
Code:
INCLUDE stm32l1xx_constants.s
; Load Constant Definitions
INCLUDE stm32l1xx_tim_constants.s ; TIM Constants
AREA
factorial, CODE, READONLY
EXPORT
__main
; make __main visible to linker
ENTRY
__main
PROC
MOV r1, #1
; kq = 1
MOV r0, #5
;n=5
MOV r2, #1
;i=1
loop
CMP r2, r0
; so sanh i voi n
BGT next
; vao stop neu lon hon
MUL
r1, r1, r2
; kq = kq*i
ADD
r2, r2, #1
; i= i+1
B
loop
next
STR
stop
LDR
r3, =result
r1, [r3]
B
stop
ENDP
ALIGN
AREA
myData, DATA, READWRITE
ALIGN
result
END
DCD
0
; dead loop & program hangs here
6.15. 2Dmatrix
Đề : Khi một ma trận 2 chiều (2D) được khai báo trong chương trình C. Ma trận
trong thực tế được lưu trong một mảng một chiều trong bộ nhớ. Chương trình C sử
dụng một cách tiếp cận theo hàng để chuyển đổi ma trận hai chiều thành mảng một
chiều. Ví dụ sau đây là cách lưu trữ một ma trận 3*3 trong bộ nhớ.
………
Dịch chương trình C sau sang chương trình asm . Chương trình asm phải chứa hai
vòng lặp
Int a[4][3] = {
{11, 12, 13}
{21, 22, 23}
{31, 32, 33}
{41, 42, 43}
};
Void main (void){
int i, j ;
for(i =0 ; i < 4 ; i ++){
for (j = 0 ; j< 3 ; j++)
a[i][j] = 2*a[i][j];
return;
}
Code:
INCLUDE stm32l1xx_constants.s
; Load Constant Definitions
INCLUDE stm32l1xx_tim_constants.s ; TIM Constants
AREA
main, CODE, READONLY
EXPORT
__main
; make __main visible to linker
ENTRY
__main
PROC
; r0 = &matrix[0], r1 = row, r2 = col, r3 = &row or &col, r4 = a[i][j], r5 = i, r6 = j, r7 =
&a[i][0]
LDR r0, =matrix
; r0 = &matrix[0]
LDR r3, =row
LDR r1, [r3]
; so luong hang = 4
LDR r3, =col
LDR r2, [r3]
; so luong cot = 3
MOVS
r5,#0
;i=0
B
check_i
loop_i
MOVS
r6,#0
B
check_j
;j=0
loop_j
MUL r7,r5,r2
; r7 = i * so luong cot
ADD r7,r0,r7,LSL #2
dau tien cua hang thu i
; r7 = &matrix[0] + 4 * r7 = &a[i][0] - phan tu
LDR r4,[r7,r6,LSL #2]
MOV
r8, #2
MUL
r4, r4, r8
; r4 = a[i][j]
; a[i][j] = 2*a[i][j];
STR r4,[r7,r6,LSL #2]
; luu vao bo nho a[i][j]
ADDS
; j++
r6,r6,#1
check_j
CMP r6,r2
; so sanh j voi so luong cot
BLT loop_j
; for(j = 0; j < 3; j++)
ADDS
r5,r5,#1
; neu j >= 3 thi i++
check_i
CMP r5,r1
BLT
; so sanh i voi so hang
loop_i
stop
; for(i = 0; i < 4; i++)
B
stop
; dead loop & program hangs here;
ENDP
ALIGN
AREA
myData, DATA, READWRITE
ALIGN
matrix
DCD
11, 12, 13, 21, 22, 23, 31, 32, 33, 41, 42, 43
; moi phan tu 32 bit - ma tran 4-3
row
DCD 4
col
DCD 3
END
6.16. MatrixTranspose
Đề : Viết chương trình asm chuyển chuyển vị ma trận xác định ở bài trước. Chương
trình asm phải có hai vòng lặp . Ma trận [aij] m*n chuyển đổi thành [aij] n*m
Code:
INCLUDE stm32l1xx_constants.s
; Load Constant Definitions
INCLUDE stm32l1xx_tim_constants.s ; TIM Constants
AREA
main, CODE, READONLY
EXPORT
__main
; make __main visible to linker
ENTRY
__main
PROC
LDR
r0, =matrix
BL
transpose
stop
B
; &p
stop
ENDP
transpose
PROC
PUSH {r4-r7, lr}
MOV
r1, #0
;i=0
loop_i
CMP
r1, #4
BGE
exit_i
ADD
r2, r1, #1
loop_j
CMP
;j=i+1
r2, #3
BGE
exit_j
; *p = &matrix[0][0]
; r4 = p + (3*i + j)*4 - r4 chua dia chi cua phan tu a[i][j]
ADD
r4, r1, r1, LSL #1
; r4 = 3*i
ADD
r4, r0, r4, LSL #2
; 4*r4 + p = 4*3*i + p
ADD
r4, r2, LSL #2
; 4*3*i + p + 4*j = (3i +j)*4 + p
; r5 = p + (3*j + i)*4 - r5 chua dia chi cua phan tu a[j][i]
;ADD r5, r2, r2, LSL #1
; r5 = 3*j
MOV
r5, r2, LSL #2
; r5 = 4*j
ADD
r5, r0, r5, LSL #2
; 4*r5 + p = 4*4*j + p
ADD
r5, r1, LSL #2
; 4*4*j + p + 4*i = 4(4j + i ) + p
;swap
LDR
r6, [r4]
LDR
r7, [r5]
STR
r7, [r4]
STR
r6, [r5]
ADD
r2, r2, #1
B
loop_j
exit_j
B
exit_i
ADD
r1, r1, #1
POP
{r4-r7, lr}
loop_i