嵌入式 ARM 汇编编程例题(二维数组按规律求和,求两数 gcd / lcm,求数组 min / max,字符串复制,排序)
Posted 繁凡さん
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了嵌入式 ARM 汇编编程例题(二维数组按规律求和,求两数 gcd / lcm,求数组 min / max,字符串复制,排序)相关的知识,希望对你有一定的参考价值。
文章目录
- 0x00. 整数加减乘除
- 0x01. 一维数组按某种规律求和
- 0x02. 二维数组按某种规律求和
- 0x03. 求两数的最大公约数
- 0x04. 求两数的最小公倍数
- 0x05. 对一维数组进行排序
- 0x06. 求一维数组中的最大值 / 最小值
- 0x07. 字符串的复制
期末上机考试题目!
(只能用纯 ARM 汇编…不能调用 C 语言 ><)
0x00. 整数加减乘除
area test, code, readonly
entry
mov r0, #2
mov r1, #8
getadd
add r2, r1, r0 ; r2 = r1 + r0
getsub
sub r3, r1, r0 ; r3 = r1 - r0
getmul
mul r4, r1, r0 ; r4 = r1 * r0
getdiv ; r5 = r1 / r0
sub r1, r1, r0
add r5, r5, #1
cmp r1, #0
bgt getdiv
stop
b stop
end
r2 = r1 + r0 = 0x0A = 10 \\textr2 = r1 + r0 = 0x0A = 10 r2 = r1 + r0 = 0x0A = 10
r3 = r1 - r0 = 0x06 = 6 \\textr3 = r1 - r0 = 0x06 = 6 r3 = r1 - r0 = 0x06 = 6
r4 = r1 * r0 = 0x10 = 16 \\textr4 = r1 * r0 = 0x10 = 16 r4 = r1 * r0 = 0x10 = 16
r5 = r1 / r0 = 0x04 = 4 \\textr5 = r1 / r0 = 0x04 = 4 r5 = r1 / r0 = 0x04 = 4
0x01. 一维数组按某种规律求和
0x01.1 求 1~100 之和
代码
area text, code, readwrite
entry
mov R0, #100 ; R0=100
mov R1, #0 ; R1=0
loop
add R1, R1, R0 ; R1=R1+R0
subs R0, R0, #1 ; R0=R0-1
cmp R0, #0 ; 根据下一条指令来对R0,0进行比较
bne loop ; bne: 若R0 ≠ 0, 跳转至loop函数处循环执行。否则,就跳过loop函数继续执行
ldr R2, =result
str R1, [R2] ; 把R1的值存到R2所指定的地址中
result
dcd 0
stop
b stop
end
运行结果
r1 = 0x00013BA = 5050
0x01.2. 求一维数组的和
结果放置在 0x300000
area getsum, code, readonly
entry
ldr r0, =src
ldr r5, =0x300000
mov r3, #len ; r3=len, 数组长度
mov r1, #0 ; r1保存总和
loop
ldr r2, [r0] ; r1为数组当前值
add r1, r1, r2
add r0, r0, #4 ; 地址指针r0后移1位
sub r3, r3, #1 ; r3--
cmp r3, #0
bne loop
stop
str r1, [r5]
b stop
area array, data, readwrite
src dcd 1, 2, 3, 4, 5, 6, 7, 8, 9
len equ 9
end
运行结果
1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 = 45 1+2+3+4+5+6 +7+8+9=45 1+2+3+4+5+6+7+8+9=45
得到的结果 r1 = 0x02D = 45 \\textr1 = 0x02D = 45 r1 = 0x02D = 45
结果存放在 0x300000 处
0x01.2. 求一维数组的所有奇数的和
代码
area getsum, code, readonly
entry
ldr r0, =src
mov r3, #len ; r3=len, 数组长度
mov r1, #0 ; r1保存总和
loop
ldr r2, [r0] ; r1为数组当前值
and r5, r2, #1
cmp r5, #0
addne r1, r1, r2 ; 如果是奇数就加上
add r0, r0, #4 ; 地址指针r0后移1位
sub r3, r3, #1 ; r3--
cmp r3, #0
bne loop
stop
b stop
area array, data, readwrite
src dcd 1, 2, 3, 4, 5, 6, 7, 8, 9
len equ 9
end
1 + 3 + 5 +7 + 9 = 25 \\text1 + 3 + 5 +7 + 9 = 25 1 + 3 + 5 +7 + 9 = 25
得到的结果 r1 = 0x019 = 25 \\textr1 = 0x019 = 25 r1 = 0x019 = 25
0x02. 二维数组按某种规律求和
听说不考二维数组()
0x02.1. 求二维数组的和
0x02.2. 求二维数组的所有奇数的和
0x03. 求两数的最大公约数
使用更相减损术计算 gcd \\gcd gcd
area getgcd, code, readonly
entry
start
mov r1, #50 ; r1 = 50
mov r2, #30 ; r2 = 30
loop
cmp r1, r2
subhi r1, r1, r2 ; 若r1>r2, r1=r1-r2
subls r2, r2, r1 ; 若r1<r2, r2=r2-r1
cmp r1, r2
bne loop ; 若 r1=r2, 退出循环
stop
b stop
end
运行结果
gcd
(
30
,
50
)
=
10
\\gcd(30,50)=10
gcd(30,50)=10
r1 = r2 = gcd = 0x0A = 10 \\textr1 = r2 = gcd = 0x0A = 10 r1 = r2 = gcd = 0x0A = 10
0x04. 求两数的最小公倍数
代码
lcm ( a , b ) = a × b gcd ( a , b ) \\textlcm(a,b)=\\cfrac a\\times b\\gcd(a, b) lcm(a,b)=gcd(a,b)a×b
area getlcm, code, readonly
entry
start
mov r1, #50 ; r1 = 50
mov r2, #30 ; r2 = 30
mul r3, r1, r2 ; r3 = r1 * r2
loop
cmp r1, r2
subhi r1, r1, r2 ; 若r1 > r2, r1 = r1 - r2
subls r2, r2, r1 ; 若r1 < r2, r2 = r2 - r1
cmp r1, r2
bne loop ; 若 r1 = r2, 退出循环
lcm ; lcm = a * b / gcd(a, b)
sub r3, r3, r1 ; arm 没有出发操作,因此使用模拟除法
add r4, r4, #1
cmp r3, #0
bgt lcm
stop
b stop
end
运行结果
r 4 = 0 x 96 = 150 r4 = 0x96 = 150 r4=0x96=150
lcm(30, 50) = 150 \\textlcm(30, 50) = 150 lcm(30, 50) = 150
0x05. 对一维数组进行排序
0x05.1. 冒泡排序
代码
; 冒泡排序
area sort, code, readonly
entry
start
mov R4, #0 ; R4=0
ldr R6, =src ; R6=src ,此时R6指向数组的开头
add R6, R6, #len ; R6=R6+len ,此时R6指向数组的末尾
outer
ldr R1, =src ; 开始外围循环
inner
ldr R2, [R1] ; 获取地址R1中的数字 R2=a[i]
ldr R3, [R1, #4] ; 获取R1的下一个地址的数字 R3=a[i+1]
cmp R2, R3 ; 根据下一条指令来对R2,R3进行比较
strgt R3, [R1] ; 如果R2>R3:
strgt R2, [R1, #4] ; 交换R2,R3地址
add R1, R1, #4 ; 地址指针R1后移一位
cmp R1, R6 ; 根据下一条指令来对R1,R6进行比较(R1: 当前位置, R6: 数组末尾)
blt inner ; blt: 小于(有符号数)如果R1<R6, 则跳转至inner处继续循环执行inner
add R4, R4, #4 ; R4=R4+4 全局指针后移一位
cmp R4, #len ; 根据下一条指令来对R4,len进行比较(R4: 当前位置, len: 数组长度)
suble R6, R6, #4 ; 如果没有走到末尾
ble outer ; 跳转至outer处继续循环执行outer
stop
b stop
area array, data, readwrite
src dcd 2, 5, 3, 1, 11, 10, 20
len equ 7 * 4
end
运行结果
R6 = src = 0x804C
\\textR6 = src = 0x804C
R6 = src = 0x804C
从 r6 \\textr6 r6 开始,排序结果为: 1 , 2 , 3 , 5 , 10 , 11 , 20 1, 2, 3, 5, 10, 11, 20 1,2,3,5,10,11,20
0x06. 求一维数组中的最大值 / 最小值
代码
area getminmax, code, readonly
entry
ldr r0, =src
mov r5, #len ; r5=len, 数组长度
ldr r7, [r0] ; r7为最大值
ldr r6, [r0] ; r6为最小值
loop
add r0, r0, #4 ; 地址指针r0后移1位
ldr r1, [r0] ; r1为数组当前值
sub r5, r5, #1 ; r5--
cmp r7, r1
movcc r7, r1 ; 产生错位,也即r7<r1, 使得r7=r1
cmp r6, r1
movcs r6, r1 ; 未产生错位,也即r6>r1, 使得r6=r1
cmp r5, #0
bne loop
stop
b stop
area array, data, readwrite
src dcd 2, 5, 3, 1, 11, 10, 15
len equ 7
end
运行结果
r6
\\textr6
r6 为最小值,
r6 = 1
\\textr6 = 1
r6 = 1
r7
\\textr7
r7 为最大值,
r7 = 0xF = 15
\\textr7 = 0xF = 15
r7 = 0xF = 15
0x07. 字符串的复制
0x07.1. 字符串的复制
area strcpy, code, readonly
entry
ldr r0, =src
ldr r1, =des
loop
ldrb r2, [r0], #1
strb r2, [r1], #1
cmp r2, #0
bne loop
stop
b stop
area string, data, readwrite
src dcb "abcdefghijklmn\\0"
des dcb ""
end
0x07.2. 从某地址处连续读取复制 100 个字符到目的地址标号 DIST 处
area strcpy, code, readonly
dist dcb "123456789……01234567890"
entry
strcpys
stmfd r13!,r0-r3
mov r0, #0x400
ldr r1,= dist
mov r2,#100
loop
subs r2, r2, #1
ldrb r3, [r0], #1
strb r3,[r1],#1
bne loop
ldmfd r13!,r0-r3
mov pc, lr
end
以上是关于嵌入式 ARM 汇编编程例题(二维数组按规律求和,求两数 gcd / lcm,求数组 min / max,字符串复制,排序)的主要内容,如果未能解决你的问题,请参考以下文章
嵌入式 ARM 汇编编程例题(二维数组按规律求和,求两数 gcd / lcm,求数组 min / max,字符串复制,排序)
嵌入式 ARM 汇编编程例题(二维数组按规律求和,求两数 gcd / lcm,求数组 min / max,字符串复制,排序)