我试图在手臂组装中进行插入排序,但我不知道如何使用2个条件进行while循环?我从维基百科得到了这个算法的伪代码,但我在将while循环转换为ARM指令时遇到了麻烦,因为有2个条件。
for i = 1 to length(A)
x = A[i]
j = i - 1
while j >= 0 and A[j] > x
A[j+1] = A[j]
j = j - 1
end while
A[j+1] = x
end for
这是我尝试将代码转换为ARM汇编指令,该数组包含20个整数:
MOV R7, #0 ;intialize index
ForLoop:
CMP R7, #20 ;check if end of array
BEQ EndFor ;exit for loop if done
LDR R1, =array ;Load array address
MOV R2, R7, LSL #2 ;multiply array index r7 by 4 to get array offset
ADD R2, R1, R2 ;Set R2 to element address
LDR R1, [R2] ;R1 = A[R7]
MOV R8, R1 ;R8 = R1
SUB R9, R7, #1 ;R9 = R7 - 1
LDR R1, =array ;Load array address
MOV R2, R9, LSL #2 ;multiply array index r9 by 4 to get array offset
ADD R2, R1, R2 ;Set R2 to element address
LDR R3, [R2] ;r3 = A[r9]
WhileLoop:
CMP R9, #0 ;while >= 0
BEQ Endwhile
CMP R3, R8 ;while R3> R8
BEQ Endwhile
LDR R1, =array ;Load array address
MOV R2, R9, LSL #2 ;multiply array index r9 by 4 to get array offset
ADD R2, R1, R2 ;Set R2 to element address
LDR R3, [R2] ;r3 = A[r9]
ADD R9, R9, #1 ;R9 = R9 + 1
LDR R1, =array ;Load array address
MOV R2, R9, LSL #2 ;multiply array index by 4 to get array offset
ADD R2, R1, R2 ;Set R2 to element address
STR R3, [R2] ;A[R9] = R3
SUB R9, R9, #1 ;R9 = R9 - 1
B WhileLoop
Endwhile:
ADD R9, R9, #1 ;R9 = R9 + 1
LDR R1, =array ;Load array address
MOV R2, R9, LSL #2 ;multiply array index by 4 to get array offset
ADD R2, R1, R2 ;Set R2 to element address
STR R8, [R2] ;A[R9] = R8
ADD R7, R7, #1 ;increment index
B ForLoop
EndFor:
当我运行程序时,我的代码在while循环中以无限循环运行。任何帮助都将非常感谢。
答案 0 :(得分:1)
while j >= 0 and A[j] > x
A[j+1] = A[j]
j = j -1
将是
while 1
if (j<0) break;
if (a[j] <= x) break;
A[j+1] = A[j]
j = j -1
您的代码正在检查j == 0和A [j] == 0而不是
也在你的循环内,你将R9增加到A [j + 1],但不是恢复它
而不是手动计算“+1”,你可以做一个偏移'LDR R3, [R2, #4]
,这将为你做“+1”
答案 1 :(得分:0)
你的问题是你对这条线路有困难; while j >= 0 and A[j] > x
。编译器实现 OR 和 AND 的方式如下,
AND_CASE:
tst cond1
bxx end_loop ; false 1st condition
tst cond2
bxx end_loop ; false 2nd condition
; true code
b AND_CASE
end_loop:
OR_CASE:
tst cond1
bxx true ; short circuit (doesn't do 2nd statement)
tst cond2
bxx end_loop ; false 2nd condition
true:
; true code
b OR_CASE
end_loop:
对于您的情况,您检查索引然后使用它。
AND_CASE:
tst reg_j ; testing index 'j'
bmi end_loop ; false
; r0 represents some free scratch register...
ldr r0, [reg_a, reg_j, LSL #2] ; get the memory
cmp r0,reg_x ; compare vs key
blt end_loop ; false
; true code
b AND_CASE
end_loop:
验证条件是否适合您的签名。重要的一点是编译器一次测试一个条件,然后根据它是 OR 还是 AND 进行分支;分支的条件只是颠倒了。汇编程序员通常必须做与编译器相同的事情。对于if
,for
等语句及其条件,每件事都是相同的。
你的基本结构是正确的,但我认为你需要将ldr
移动到'测试块'而不是把它包含在其他地方;即第二次条件测试。同样,你需要让你的标志和条件正确。我宁愿不提供这些信息,因为它是写记忆和学习的好练习。