我正在努力学习ARM汇编,我发现了这个练习并试图解决它。
我做了这段代码,但我真的不知道如何修复和继续它,因为我知道有些部分缺失了。我第一次试着做和的部分,但不明白如何做前5个数字和其他数字的平均值。
这就是练习:
给定N=21个正整数的向量V[],存储从内存位置0x100开始的变量。
-计算前5个数字的和,然后计算余数的平均值
-确定两个值中的较大值和较小值获得并将第一个存储在位置0x200,将第二个存储在0x500
这是我制作的代码,我正试图完成并修复:
ENTRY
MOV R0, #21 ; Counter for array
LDR R1, =array ; Register for array
loop LDR R2, [R1], #20 ; Loading value from array and updating(increment) the address
ADD R3,R3,R2 ; Sum is stored in R3 register
SUB R0,R0,#1 ; Decrementing counter value
CMP R0,#00 ; Checking counter value
BNE loop
END
编辑:我做了一些事情,这是结果,不是最终结果,因为我必须检查它在我的机器上是否正常工作。
MOV R0, #21 ; Counter array
LDR R1, =array, #0x100 ; Array at 0x100
loopsum LDR R2, [R1], #20 ; Loading value from array and updating(increment) the address
ADD R3,R3,R2 ; Put sum in R3
SUB R0,R0,#1 ; decrease counter
CMP R0,#16 ; check if first 5
Bne loopsum
loopmean LDR R2, [R1], #16 ; Loading value from array and updating(increment) the address
ADD R4,R4,R2 ; put sum in R4
SUB R0,R0,#1 ; decrease counter
CMP R0,#0 ; check if ended
Bne loopmean
MOV R4, R4, ASR 16 ;divide by 16
MOV R5, #0x200 ;address for max
MOV R6, #0x500 ;address for min
CMP R3, R4 ;R3 > R4 ?
MOVgt R5, R3 ;if yes puts R3 in R5
MOVle R6, R4 ;R4 in R6
CMP R4, R3 ;R4 > R3 ?
MOVgt R5, R4 ;if yes puts R4 in R5
Movle R6, R3 ;R3 in R6
END
我理解你的教授想要教什么,但他应该先教AAPCS
,以及如何使例程正确地分离函数IMO.
以下是三个功能:
- void myFunc(uint32_t*pArray,uint32.t*p Lesser,uint22_t*p Greater(
- void myFunc_mf(uint32_t*pArray,uint32.t*p较小,uint22_t*p较大(
- void myFunc_bfmf(uint32_t*p数组,uint32.t*p较小,uint22_t*p较大(
正如参数名称所示,您应该分别用参数0x100、0x500和0x200来调用它们,以满足教授的要求
第一个(myFunc(可能是您的教授所期望的:运行循环。
第二个和第三个通过展示一个真正的汇编程序员如何在ARM整数核或NEON上处理这个问题,展示了对这个有点愚蠢和不切实际的任务的中指(也是一个很大的问题(。
请注意,霓虹灯版本是最短的。
.syntax unified
.arm
.arch armv7-a
.fpu neon
.global myFunc, myFunc_mf, myFunc_bfmf
.text
.balign 64
.func
// void myFunc(uint32_t *pArray, uint32_t *pLesser, uint32_t *pGreater);
pArray .req r0
pLesser .req r1
pGreater .req r2
counter .req r3
sum .req r12
mean1 .req r6
mean2 .req r7
lesser .req pArray
greater .req mean2
myFunc:
push {r4-r7}
mov counter, #5
mov sum, #0
mov mean1, #0
mov mean2, #0
b 1f
.balign 64
1:
ldr r4, [pArray], #4
subs counter, counter, #1
add sum, sum, r4
bne 1b
/////////////////////////////////////////////////////
mov counter, #16
b 1f
.balign 64
1:
ldrd r4, r5, [pArray], #8
subs counter, counter, #2
add mean1, mean1, r4
add mean2, mean2, r5
bne 1b
add mean1, mean2, mean1
lsr mean1, mean1, #4
/////////////////////////////////////////////////////
cmp mean1, sum
mov greater, mean1
mov lesser, sum
movlo greater, sum
movlo lesser, mean1
str greater, [pGreater]
str lesser, [pLesser]
pop {r4-r7}
bx lr
.endfunc
.balign 64
.func
myFunc_mf:
push {r4-r11}
ldmia pArray!, {r4-r8}
add r4, r5, r4
add r6, r7, r6
add r4, r4, r8
add r3, r4, r6
ldmia pArray!, {r4-r11}
add r4, r5, r4
add r6, r7, r6
add r8, r9, r8
add r10, r11, r10
add r4, r6, r4
add r8, r10, r8
add r12, r8, r4
ldmia pArray, {r4-r11}
add r4, r5, r4
add r6, r7, r6
add r8, r9, r8
add r10, r11, r10
add r4, r6, r4
add r8, r10, r8
add r12, r4, r12
add r12, r12, r8
lsr r12, r12, #4
cmp r12, r3
mov r4, r12
mov r5, r3
movlo r4, r3
movlo r5, r12
str r4, [pGreater]
str r5, [pLesser]
pop {r4-r11}
bx lr
.endfunc
.balign 64
.func
myFunc_bfmf:
vmov.i32 d2, #0
vld1.32 {q0}, [pArray]!
vld1.32 {d2[0]}, [pArray]!
vld1.32 {q2, q3}, [pArray]!
vld1.32 {q8, q9}, [pArray]
vpaddl.u32 q0, q0
vpaddl.u32 q2, q2
vpaddl.u32 q3, q3
vpadal.u32 d0, d2
vpadal.u32 q2, q8
vpadal.u32 q3, q9
vadd.u64 d0, d0, d1
vadd.u64 q2, q3, q2
vadd.u64 d4, d5, d4
vshr.u64 d1, d4, #4
vmax.u32 d2, d1, d0
vmin.u32 d3, d1, d0
vst1.32 {d2[0]}, [pGreater]
vst1.32 {d3[0]}, [pLesser]
bx lr
.endfunc
.end