我尝试在给定的C bubblesort代码的基础上在ARM Assembler中编写一个简单的bubblesort:
bubbleSort (int A[], int n)
{
int temp;
int i;
do {
swapped = false;
n = n-1;
for (i=0; i < n; i++) {
if ( A[i] > A[i+1] ) {
temp = A[i];
A[i] = A[i+1];
A[i+1] = temp;
swapped = true;
}
}
} while (swapped == true);
}
这是我到目前为止编写的汇编代码:
bubblesort:
@ maybe r0, r1 for table and counter (rest is based on that)
@ r8 = Buffer for Value
@ r4 = Counter for loop1
@ r5 = Register for Value
@ r7 = Register for Value
@ r1 = Size of Array
@ r0 = Address of the 1. Element
@ r10 = "swapped" register
loop:
mov r10, #0
sub r1, #1 @ Decrement Counter for loop
loop1:
ldr r5, [r0]
ldr r7, [r0, #4]
cmp r5, r7
movgt r8, r7
movgt r7, r5
movgt r5, r8
strgt r5, [r0]
strgt r7, [r0, #4]
movgt r10, #1
cmp r4, r1 @ compare r4 and r1
add r4, #1 @ Increment counter for loop1
blt loop1 @ is r4 < r1 ? yes = go to loop1
cmp r10, #1
beq loop
我的目标是对一系列整数或“数组”进行排序。给定参数是第一个值(r0)和表大小(r1)的地址。 将存储器中的值加载到寄存器中,进行比较,然后交换寄存器中的值并将它们存储在存储器中。
之前我改变了我的代码我运行了调试器,寄存器中的“交换”部分似乎工作正常。但我不太确定我在那里做的循环逻辑。 我的问题是,当我查看内存时,第一个值被正确排序,然后它就会停止排序/忽略其余值。
现在我得到的是一个无限循环。
我将非常感谢任何给定的帮助。
如果有什么我忘记提及的,请告诉我,我会提供。
提前致谢,
与Dethe
答案 0 :(得分:0)
@ ---- Added ----
@ bubblesort.s
@
@ pi@RPi3:~ $ as -o bubblesort.o bubblesort.s
@ pi@RPi3:~ $ gcc -o bubblesort bubblesort.o
@ pi@RPi3:~ $ ./bubblesort; echo $?
.data
table:
.word 9, -8, -7, 6, -5, 4, -3, 2, -1, 0, 127, -128
aft_table:
.balign 4
n:
.word (aft_table - table) >>2
.text
.global main
main:
push {r4-r10, lr}
ldr r1, =n
ldr r1, [r1] @ len(table) in r1
@ ---------------
bubblesort:
@ maybe r0, r1 for table and counter (rest is based on that)
@ r8 = Buffer for Value
@ r4 = Counter for loop1
@ r5 = Register for Value
@ r7 = Register for Value
@ r1 = Size of Array
@ r0 = Address of the 1. Element
@ r10 = "swapped" register
loop:
mov r10, #0
sub r1, #1 @ Decrement Counter for loop
@ ---- Added ----
ldr r0, =table
mov r4, #1 @ i = 1 i could = 0, if instructions
@ cmp r4, r1 @ compare r4 and r1
@ add r4, #1 @ Increment counter for loop1
@ were reversed
@ ---------------
loop1:
ldr r5, [r0]
ldr r7, [r0, #4]
cmp r5, r7
movgt r8, r7
movgt r7, r5
movgt r5, r8
strgt r5, [r0]
strgt r7, [r0, #4]
movgt r10, #1
@ ---- Added ----
add r0, #4 @ Index table to next position
@ ---------------
cmp r4, r1 @ compare r4 and r1
add r4, #1 @ Increment counter for loop1
blt loop1 @ is r4 < r1 ? yes = go to loop1
cmp r10, #1
beq loop
@ ---- Added ----
exit:
pop {r4-r10, lr}
mov r0, #0 @ good return code
bx lr @ Exit with gcc linker
@ ---------------
您的代码逻辑很好。我已经添加了几个部分来编译和运行它,它在您的代码中标记。需要注意两件事,mov r4, #1
开始计数,add r0, #4
将表格指针移动到下一个位置。
我还将包括我的调试脚本,这些脚本有助于查找错误并帮助理解交换开关(通过将-128更改为128,更少通过循环)。
@ ---- Added ----
@ bubblesort2.s
@
@ pi@RPi3:~ $ as -o bubblesort2.o bubblesort2.s
@ pi@RPi3:~ $ gcc -o bubblesort2 bubblesort2.o
@ pi@RPi3:~ $ ./bubblesort2; echo $?
.data
table:
.word 9, -8, -7, 6, -5, 4, -3, 2, -1, 0, 127, 128
aft_table:
.balign 4
n:
.word (aft_table - table) >>2
@ ---------------
@ ---- Added ----
.balign 4 @ Prt
frmt: @ Prt
.asciz "%d " @ Prt
.balign 4
flags: @ RDmp
.word 0 @ RDmp
msg: @ RDmp
.asciz "NZCV 2> 6= 8<\n" @ RDmp
aft_msg: @ RDmp
@ RDmp
l_msg: @ RDmp
.word (aft_msg - msg) - 1 @ RDmp
@ ---------------
.text
.global main
.global printf, putchar @ Prt
main:
push {r4-r10, lr}
ldr r1, =n
ldr r1, [r1] @ len(table) in r1
bl Print @ Prt
@ ---------------
bubblesort:
@ maybe r0, r1 for table and counter (rest is based on that)
@ r8 = Buffer for Value
@ r4 = Counter for loop1
@ r5 = Register for Value
@ r7 = Register for Value
@ r1 = Size of Array
@ r0 = Address of the 1. Element
@ r10 = "swapped" register
loop:
mov r10, #0
sub r1, #1 @ Decrement Counter for loop
@ ---- Added ----
ldr r0, =table
mov r4, #1 @ i = 1 i could = 0, if instructions
@ cmp r4, r1 @ compare r4 and r1
@ add r4, #1 @ Increment counter for loop1
@ were reversed
@ ---------------
loop1:
ldr r5, [r0]
ldr r7, [r0, #4]
cmp r5, r7
movgt r8, r7
movgt r7, r5
movgt r5, r8
strgt r5, [r0]
strgt r7, [r0, #4]
movgt r10, #1
@ ---- Added ----
add r0, #4 @ Index table to next position
@ ---------------
cmp r4, r1 @ compare r4 and r1
add r4, #1 @ Increment counter for loop1
blt loop1 @ is r4 < r1 ? yes = go to loop1
@ ---- Added ----
bl Print @ Prt
bl RDmp @ RDmp
@ ---------------
cmp r10, #1
beq loop
@ ---- Added ----
exit:
pop {r4-r10, lr}
mov r0, #0 @ good return code
bx lr @ Exit with gcc linker
@ ---------------
@ ---- Added ----
Print: @ Prt, table to stdout
push {r0-r10, lr} @ Prt
mrs r10, cpsr @ Prt
ldr r2, =n @ Prt
ldr r2, [r2] @ Prt
ldr r3, =table @ Prt
lp: @ Prt
ldr r0, =frmt @ Prt
ldr r1, [r3], #4 @ Prt
push {r0-r3} @ Prt
bl printf @ Prt
pop {r0-r3} @ Prt
subs r2, #1 @ Prt
bne lp @ Prt
mov r0, #0xa @ Prt
bl putchar @ Prt
msr cpsr_f, r10 @ Prt
pop {r0-r10, lr} @ Prt
mov pc, lr @ Prt
@ ---------------
@ ---- Added ----
RDmp: @ RDmp
push {r0-r10, lr} @ RDmp
mrs r10, cpsr @ RDmp
push {r8-r11} @ RDmp
push {r4-r7} @ RDmp
push {r0-r3} @ RDmp
@ RDmp
ldr r1, =flags @ RDmp
mrs r0, cpsr @ RDmp
str r0, [r1] @ RDmp
b seq @ RDmp
@ RDmp
p_char: @ RDmp
push {r0-r4, lr} @ RDmp
bl putchar @ RDmp
pop {r0-r4, lr} @ RDmp
mov pc, lr @ RDmp
@ RDmp
register: @ RDmp
mov r1, #0 @ RDmp
push {r0, lr} @ RDmp
@ RDmp
nibble: @ RDmp
mov r2, r3 @ RDmp
lsl r2, r1 @ RDmp
lsr r2, #28 @ RDmp
add r2, #48 @ RDmp
cmp r2, #58 @ RDmp
addge r2, #39 @ RDmp
mov r0, r2 @ RDmp
bl p_char @ RDmp
add r1, #4 @ RDmp
cmp r1, #32 @ RDmp
blt nibble @ RDmp
mov r0, #32 @ RDmp
bl p_char @ RDmp
pop {r0, lr} @ RDmp
mov pc, lr @ RDmp
@ RDmp
manage: @ RDmp
push {r0, lr} @ RDmp
mov r3, r4 @ RDmp
bl register @ RDmp
mov r3, r5 @ RDmp
bl register @ RDmp
mov r3, r6 @ RDmp
bl register @ RDmp
mov r3, r7 @ RDmp
bl register @ RDmp
pop {r0, lr} @ RDmp
mov pc, lr @ RDmp
@ RDmp
seq: @ RDmp
pop {r4-r7} @ RDmp
bl manage @ RDmp
mov r0, #32 @ RDmp
bl p_char @ RDmp
pop {r4-r7} @ RDmp
bl manage @ RDmp
mov r0, #0x0a @ RDmp
bl p_char @ RDmp
@ RDmp
pop {r4-r7} @ RDmp
bl manage @ RDmp
mov r0, #32 @ RDmp
bl p_char @ RDmp
ldr r3, =flags @ RDmp
ldr r3, [r3] @ RDmp
bl register @ RDmp
@ RDmp
ldr r2, = l_msg @ RDmp
ldr r2, [r2] @ RDmp
ldr r1, =msg @ RDmp
w_msg: @ RDmp
ldr r0, [r1], #1 @ RDmp
bl p_char @ RDmp
subs r2, #1 @ RDmp
bgt w_msg @ RDmp
msr cpsr_f, r10 @ RDmp
pop {r0-r10, lr} @ RDmp
mov pc, lr @ RDmp
@ ---------------
./bubblesort2; echo $?
的输出,以“@”开头的行是我对其下方寄存器的标题注释。
9 -8 -7 6 -5 4 -3 2 -1 0 127 128
-8 -7 6 -5 4 -3 2 -1 0 9 127 128
@ (r0) (r1) (r2) (r3) (r4) (r5) (r6) (r7)
000207f0 0000000b 7ee7077c 00010450 0000000c 0000007f 00010328 00000080
@ (r8) (r9) (r10) (r11) (F)(cpsr) (F) (F val)
00000000 00000000 60000010 00000000 60000010 NZCV 2> 6= 8<
-8 -7 -5 4 -3 2 -1 0 6 9 127 128
000207ec 0000000a 7ee7077c 00010450 0000000b 00000009 00010328 0000007f
00000000 00000000 60000010 00000000 60000010 NZCV 2> 6= 8<
-8 -7 -5 -3 2 -1 0 4 6 9 127 128
000207e8 00000009 7ee7077c 00010450 0000000a 00000006 00010328 00000009
00000000 00000000 60000010 00000000 60000010 NZCV 2> 6= 8<
-8 -7 -5 -3 -1 0 2 4 6 9 127 128
000207e4 00000008 7ee7077c 00010450 00000009 00000004 00010328 00000006
00000000 00000000 60000010 00000000 60000010 NZCV 2> 6= 8<
-8 -7 -5 -3 -1 0 2 4 6 9 127 128
000207e0 00000007 7ee7077c 00010450 00000008 00000002 00010328 00000004
00000000 00000000 60000010 00000000 60000010 NZCV 2> 6= 8<
0