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 )
BÀI TẬP CHƯƠNG 8 – CHƯƠNG TRÌNH CON
(Code đính kèm)
81_SoNguyenTo
Đề: Viết một chương trình con kiểm tra thử xem một số đưa vào có phải là số
nguyên tố hay không ? Chương trình con nhận một tham số và trả về đúng hoặc sai.
Tìm tất cả các số nguyên tố trong khoảng từ 100 đến 200 ?
Code:
INCLUDE stm32l1xx_constants.s
; Load Constant Definitions
INCLUDE stm32l1xx_tim_constants.s ; TIM Constants
AREA
main, CODE, READONLY
EXPORT
linker
__main
; make __main visible to
ENTRY
__main
PROC
;r0 = flag, r1 = num, r2 = i, r3 = so du
;MOV
r1, #100
LDR
r4, =array
MOV
r1, #100
loop_
CMP
; num = 100
r1, #200
BGT
stop
BL
pri
CMP
r0, #1
STREQ
r1, [r4]
ADDEQ
r4, #4
; dia chi tang 4 byte
ADD
r1,r1,#1
; j++
B
loop_
stop
B
program hangs here
stop
; dead loop &
ENDP
pri
PROC
MOV r2, #2
;i=2
CMP r1, #1
BEQ
no
loop
CMP r2, r1
BHS yes
; so sanh i voi num
; neu i >= num thi nhay ra ngoai
UDIV r3, r1, r2
; r4 = num/i
MLS
; sodu = num -(r4*i)
r3, r2, r3, r1
CBZ r3, no
; so sanh so du voi
r0, #1
ADDNE
; la so nguyen to neu so du #0
r2, r2, #1
; i += 1
BNE loop
yes
MOV
BX
r0, #1
; set co flag len 1 - la so nguyen to
lr
no
la so nguyen to
BX
MOV
r0, #0
; khong phai
lr
ENDP
ALIGN
AREA
myData, DATA, READWRITE
ALIGN
array
DCD
0
END
81_SoNguyenTo_1
INCLUDE stm32l1xx_constants.s
; Load Constant Definitions
INCLUDE stm32l1xx_tim_constants.s ; TIM Constants
AREA
main, CODE, READONLY
EXPORT
linker
__main
; make __main visible to
ENTRY
__main
PROC
; r1 = , r2 = , r3 = , r4 = , r5 = , r6 =
LDR r6, =t
MOV r1, #99
lap
ADD
r1, #1
; r1++
CMP r1, #200
BGT stop
BL
; r1>200 break;
check
; call check
CMP r5, #1
BNE lap
; r1 khong la snt
STR r1, [r6], #4
B
; la so nguyen to , luu vao r6
lap
stop
; continue
B
stop
ENDP
check
PROC
MOV r2, r1
LSR r2, #1
; r2 = r1/2
MOV r3, #2
; r3 -> (2,r2)
loop
CMP r3, r2
BGT snt
; if(r3 > r2) la so nguyen to
UDIV r0, r1, r3
MUL
r0, r0, r3
; r0 = r1/r3
; r0 *= r3
SUB r0, r1, r0
; r0 = r0-r3; tim so du cua phep chia r1/r3
CMP r0, #0
; if(r0 == 0) khong la so nguyen to
BEQ ksnt
ADD r3, #1
B
; r3++
loop
snt
MOV r5, #1
B
; r5 = 1
stop1
ksnt
MOV r5, #0
; r5 = 0
stop1
BX
lr
ENDP
ALIGN
AREA myData, DATA, READWRITE
ALIGN
t
DCD 0
END
82_8Argument
Đề: Viết một chương trình con nhận 8 đối số nguyên và tính các sản phẩm của
những số nguyên này. Lưu ý các đối số thừa nên được chuyển đến chương trình con
thông qua ngăn xếp ?
Code:
INCLUDE stm32l1xx_constants.s
; Load Constant Definitions
INCLUDE stm32l1xx_tim_constants.s ; TIM Constants
AREA
main, CODE, READONLY
EXPORT
linker
__main
; make __main visible to
ENTRY
__main
mov
r1, #3
push {r1}
mov
r1, #4
push {r1}
mov
r1, #5
push {r1}
mov
r1, #6
push {r1}
mov
r1, #7
push {r1}
mov
r1, #8
PROC
push {r1}
mov
r1, #9
push {r1}
mov
r1, #2
push {r1}
bl
computes
stop
b
endp
computes
proc
mov
r0, #1
pop
{r1}
mul
r0,r0,r1
pop
{r1}
mul
r0,r0,r1
pop
{r1}
mul
r0,r0,r1
pop
{r1}
mul
r0,r0,r1
stop
pop
{r1}
mul
r0,r0,r1
pop
{r1}
mul
r0,r0,r1
pop
{r1}
mul
r0,r0,r1
pop
{r1}
mul
r0,r0,r1
stop1
bx
lr
endp
AREA
myData, DATA, READWRITE
ALIGN
t
array
dcd
dcd
0
2,3,4,5,6,7,8,9
END
83_MaHoaCaeserShift
Đề: Triển khai một chương trình con của mã hóa Caeser shift. Đó là một loại mã
hóa đơn giản với mỗi ký tự được thay thế bởi một ký tự khác (có nguyên tắc thay
thế) trong bảng chữ cái. Ví dụ với đoạn dịch chuyển là 3, chữ A sẽ thành chữ D, chữ
B thành chữ E…
Code:
INCLUDE stm32l1xx_constants.s
; Load Constant Definitions
INCLUDE stm32l1xx_tim_constants.s ; TIM Constants
AREA
main, CODE, READONLY
EXPORT
linker
__main
; make __main visible to
ENTRY
__main
PROC
LDR r0, =st
BL
encryption
stop
B
ENDP
encryption
PROC
loop
LDRB
r1,[r0]
CMP r1, #0
BEQ stop1
ADD r1, #3
CMP r1, #128
BLT tiep
MOV r1, #'c'
tiep
STRB r1,[r0]
stop
ADD r0,#1
B
loop
stop1
BX
lr
ENDP
AREA myData, DATA, READWRITE
ALIGN
st
DCB "ABC",0
END
84_GiaVeXemPhim
Đề: Viết một chương trình con gọi GiaVeXemPhim tính giá vé xem phim dựa vào
tham số truyền vào là độ tuổi. Nếu tuổi nhỏ hơn 12, giá vé là 6$, nếu tuổi lớn hơn
hoặc bằng 13 và bé hơn 64 giá vé là 8$, lớn hơn 65 thì giá vé là 7$…
Code:
INCLUDE stm32l1xx_constants.s
; Load Constant Definitions
INCLUDE stm32l1xx_tim_constants.s ; TIM Constants
AREA
main, CODE, READONLY
EXPORT
linker
__main
; make __main visible to
ENTRY
__main
MOV r0, #15
PROC
; so tuoi
BL
price
LDR
r2, =cost
STRB r1, [r2]
stop
B
ENDP
price
PROC
PUSH {lr}
CMP r0, #12
BLE child
CMP r0, #65
BLT adult
B
old
child
MOV r1, #6
B
stop1
adult
MOV r1, #8
B
stop1
old
MOV r1, #7
stop1
POP
ENDP
{pc}
stop
ALIGN
AREA
myData, DATA, READWRITE
ALIGN
cost
DCD
0
END
85_a_aa_aaa
Đề: Viết một chương trình con tính giá trị của biểu thức sau dựa trên hai tham số a
và n.
Sn(a) = a+ aa+ aaa + aaaa + ….+ aaa…a(n)
Ví dụ: khi a = 3 và n = 5, chúng ta có
S5(3) = 3 + 33+ 333 + 3333+ 33333
Code:
INCLUDE stm32l1xx_constants.s
; Load Constant Definitions
INCLUDE stm32l1xx_tim_constants.s ; TIM Constants
AREA
main, CODE, READONLY
EXPORT
linker
__main
; make __main visible to
ENTRY
__main
PROC
mov
r0,#2
; a=2
mov
r1,#3
; n=3
bl
sumS
; call sumS(a,n)
; ket qua luu vao r2
stop
b
stop
endp
sumS
PROC
MOV r2, #0
; i=0
MOV r3,
#10
; muoi=10
MOV r5,
#0
; kq=0
loop
; for(i=0;i
CMP r2, r1
BEQ stop1
MUL r4,
r4,
r3
; m*=10
ADD r4,
r4,
r0
; m+=a
ADD
r5,
r5,
ADD r2,
#1
B
loop
stop1
MOV r2,
r5
BX
lr
ENDP
ALIGN
r4
; kq+=m
AREA
myData, DATA, READWRITE
ALIGN
END
86_TongGiaiThua
Đề: Viết một chương trình tính tổng giai thừa . Chương trình nên sử dụng hai
chương trình con, chương trình con thứ nhất tính giai thừa n!, và chương trình con
thứ hai tính tổng của các giai thừa đó ?
Code:
INCLUDE stm32l1xx_constants.s
; Load Constant Definitions
INCLUDE stm32l1xx_tim_constants.s ; TIM Constants
AREA
main, CODE, READONLY
EXPORT
linker
__main
; make __main visible to
ENTRY
__main
PROC
MOV r0, #3
BL
; n=10
sumFactorial
; call sumS(a,n)
; r2 chua ket qua
stop
ENDP
B
stop
sumFactorial PROC
; ham thu nhat
PUSH{lr}
MOV r1, #1
;i=1
MOV r2, #0
;s=0
loop
;for(i = 1; i < n; i++)
CMP r1, r0
BGT stop1
BL
factorial
; call ham tinh giai thua
ADD r2, r2, r3
; cong cac giai thua voi nhau
ADD r1, #1
; i++
B
loop
stop1
POP{pc}
ENDP
factorial
PROC
; ham thu hai
PUSH{r0, r1, r2}
MOV
r2, #1
;j=1
MOV
r0, #1
;a=1
r2, r1
; for(int j = 1; j < i; j++)
loop2
CMP
BGT stop2
MUL
r0, r0, r2
; a *= j
ADD r2, #1
B
loop2
stop2
MOV r3, r0
; r3 = a!
POP{r0, r1, r2}
BX
lr
ENDP
ALIGN
AREA
myData, DATA, READWRITE
ALIGN
END
87_SoLuong1Bit
Đề: Viết chương trình sử dụng chương trình con để tìm có bao nhiêu 1 bits tồn tại
trong một số 32 bits
Code:
INCLUDE stm32l1xx_constants.s
; Load Constant Definitions
INCLUDE stm32l1xx_tim_constants.s ; TIM Constants
AREA
main, CODE, READONLY
EXPORT
linker
ENTRY
__main
; make __main visible to
__main
PROC
MOV r0, #12
; a = 12
BL
findBit1
stop
B
stop
ENDP
findBit1
PROC
PUSH {lr}
MOV r3, #0
; dem = 0
loop
; while(a > 0)
CMP r0, #0
BEQ stop1
MOV r1, r0
LSR r1, #1
; b = (int) a/2 ; r1 = r1/ 2^1
ADD r1, r1, r1
; b *= 2
SUB r2, r0, r1
;c=a-b
CMP r2, #0
; c == 0 countinue while
BEQ skip
ADD r3, #1
; else dem++
skip
LSR r0, #1
B
stop1
loop
POP
{pc}
;BX
lr
ENDP
ALIGN
AREA
myData, DATA, READWRITE
ALIGN
END
88_SoLuongBitKhac
Đề: Viết chương trình sử dụng chương trình con để tìm có bao nhiêu số lượng bits
khác trong một số 32 bits
Code:
INCLUDE stm32l1xx_constants.s
; Load Constant Definitions
INCLUDE stm32l1xx_tim_constants.s ; TIM Constants
AREA
main, CODE, READONLY
EXPORT
linker
__main
; make __main visible to
ENTRY
__main
PROC
LDR r0, =10
LDR r1, =5
BL
stop
bits_differ
B
stop
ENDP
bits_differ
PROC
PUSH {r4,lr}
MOV r4,
#0
loop
CMP r0,#0
BNE skip1
CMP r1,#0
BEQ stop1
skip1
LSR r2, r0, #1
; a1=a/2
ADD r2,r2,r2
; a1=2*a1
SUB r2,r0,r2
; a1=a-a1 (=0 or =1)
LSR r0,r0,#1
LSR r3, r1, #1
; a1=a/2
ADD r3,r3,r3
; a1=2*a1
SUB r3,r1,r3
; a1=a-a1 (=0 or =1)
LSR r1,r1,#1
CMP
BEQ skip
ADD r4,#1
r2,r3
skip
B
loop
stop1
MOV r0,r4
POP {r4,pc}
ENDP
ALIGN
AREA
myData, DATA, READWRITE
ALIGN
END
89_UniqueElement
Đề: Cardinality (bản số) trong một mảng được xác định số lượng các phần tử duy
nhất trong một mảng số đó. Viết một chương trình con tính cardinality của mảng số
nguyên.
Code:
INCLUDE stm32l1xx_constants.s
; Load Constant Definitions
INCLUDE stm32l1xx_tim_constants.s ; TIM Constants
AREA
main, CODE, READONLY
EXPORT
linker
ENTRY
__main
; make __main visible to
__main
BL
PROC
func
stop
B
stop
ENDP
func
PROC
PUSH {lr}
LDR
r0,
LDR r1,
=size
LDR r1,
[r1]
MOV r2, #0
MOV r5,
=array
; dua dia chi mang vao r0
; n=10
; i=0
#0
; dem=0
loop
CMP r2,
; for(i=0; i
r1
BEQ stop
LDR r3,
[r0,r2,lsl #2] ; a= A[i]
BL
check
CMP r4,
#0
; call check(a,i,n,A[]) <---> r3,r2,r1,r0
BNE skip
; if(check()) countinue, jump skip
ADD r5, #1
; else dem++
skip
ADD r2,#1
; i++ in for( , , )
B
loop
BX
lr
;co the xai pop{pc}
ENDP
check
PROC
PUSH {r0,r1,r2,r3,r5}
MOV
; check(a,i,n,A[]) <---> r3,r2,r1,r0
; luu cac gia tri nay vao ngan xep
r4,#0
; dem1=0
MOV r5, #0
;r5=j
loop1
; for(int j=0; j
CMP r5,r2
; r2=i
BEQ stop1
LDR r6, [r0,r5,lsl #2]
; b=A[j]
CMP r3,r6
; if(a==b)
BEQ tangr4
; dem1=1; and break;
ADD r5,#1
B
loop1
tangr4
MOV r4,#1
stop1
POP
{r0,r1,r2,r3,r5}
; lay bo gia tri ra khoi ngan xep
BX
lr
ENDP
ALIGN
AREA
myData, DATA, READWRITE
ALIGN
array
DCD 4,2,3,4,2,3,4,5,6,7
size
DCD 10
END
811_GiaTriBTBacHai
Đề: Viết một chương trình con asm tên f tính giá trị của biểu thức sau
f(x, y) = ax2 + bxy + c
Khi a, b, c là những hẵng số nguyên, x, y à những số nguyền truyền vào, giả sử a, b,c
được xác định trong bộ nhỡ dữ liệu , x, y là những tham số truyền vào của những
chương trình con này ?
Code:
INCLUDE stm32l1xx_constants.s
; Load Constant Definitions
INCLUDE stm32l1xx_tim_constants.s ; TIM Constants
AREA
main, CODE, READONLY
EXPORT
linker
ENTRY
__main
; make __main visible to
__main
PROC
MOV r0,
#2
;x
=2
MOV r1,
#3
;y
=3
BL
f
stop
; call f(x,y)
B
stop
ENDP
f
PROC
PUSH{lr}
MUL r1,
r1,
r0
; y*x
MUL r0,
r0,
r0
; x*x
LDR r2,
=biena
LDR r2,
[r2]
MUL
r0,
LDR r2,
=bienb
LDR r2,
[r2]
MLA r0,
r1,
LDR r2,
=bienc
LDR r2,
[r2]
ADD r0,
r2
POP{pc}
ENDP
ALIGN
; r2 = a
r0,
r2
; a*x*x
; r2 = b
r2,
r0
; a*x*x+b*x*y
; r2 = c
; a*x*x+b*x*y+c
; return
AREA myData, DATA, READWRITE
ALIGN
biena
DCD 2
;a=2
bienb
DCD 3
;b=3
bienc
DCD 4
;c=4
END
812_Fibonaci
Đề: Viết một chương trình con số trong day Fibonaci
Code:
INCLUDE stm32l1xx_constants.s
; Load Constant Definitions
INCLUDE stm32l1xx_tim_constants.s ; TIM Constants
AREA
main, CODE, READONLY
EXPORT
linker
__main
; make __main visible to
ENTRY
__main
PROC
MOV r0, #7
BL
stop
ENDP
;n=7
fibo
B
stop