无法理解如何完成此 ARM 程序集代码以完成 5 个数字的总和和余数的平均值



我正在努力学习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

最新更新