汇编中的递归插入排序
Recursive Insertion Sort in Assembly
我正在尝试在汇编 ARMV-8A 中实现插入排序。更具体地说,我试图用 C 翻译以下代码:
void insertionSortRecursive(int arr[], int n)
{
if (n <= 1)
return;
insertionSortRecursive( arr, n-1 );
int last = arr[n-1];
int j = n-2;
while (j >= 0 && arr[j] > last)
{
arr[j+1] = arr[j];
j--;
}
arr[j+1] = last;
}
我试图按原样翻译它,但我的实现在函数 loop_insertion 中进入无限循环,如调试器所示:
.data
my_Table: .space 16
size: .word 4
FileOpenMode: .string "r"
FileName: .string "test1.txt"
fscanf_str: .string "%d"
printf_str: .string "%d "
out_message_str: .string "%d "
.text
.global main
main:
stp x29,x30,[sp,-32]!
add x29,sp,0
adr x1,FileOpenMode
adr x0,FileName
bl fopen
mov x20,x0
adr x0,my_Table
mov x22,x0 //x22 adr of table
mov x21,4
mov x23,0
//**************** READ FROM FILE ******************
loop:
add x2,x29,28
adr x1,fscanf_str
mov x0,x20
bl fscanf
ldr w1,[x29,28]
mov x0,x22
str w1,[x0,x23]
add x23,x23,4
add w21,w21,-1
cbnz w21,loop
//********************************************
mov x0,x22 //adr of table
mov x1,4
bl insertion_sort
//**************** PRINT TO SCREEN FROM TABLE *****************
mov x21,0
mov x23,4
loop_print:
adr x0, out_message_str
ldr w1,[x22,x21]
bl printf
add x21,x21,4
sub x23,x23,1
cbnz x23,loop_print
//***********************************************************
ldp x29, x30, [sp], 32
ret
insertion_sort:
stp x29,x30,[sp,-64]!
add x29,sp,0
str x19,[x29,32] //str the save register
str x0,[x29,16] //str the address of table
str w1,[x29,24] //str the n
mov x19,4
cmp w1,1
b.le exit_ins
sub w1,w1,1
bl insertion_sort
ldr w9,[x29,24] //load the n for the suitable function
sub w9,w9,1 //n-1
mul w9,w9,w19
ldr x10,[x29,16] //adr table
ldr w11,[x10,x9] //last
udiv w9,w9,w19
sub w12,w9,1 //j=n-2
loop_insertion:
ldr w12,[x29,24]
cmp w12,0
b.lt label1
mul w12,w12,w19
ldr w13,[x10,x12] // w13=arr[j]
cmp w13,w11
b.le label1
add w12,w12,w19
str w13,[x10,x12] //arr[j+1]=w13
udiv w12,w12,w19
sub w12,w12,1
str w12,[x29,24]
b loop_insertion
label1:
add w12,w12,1
mul w12,w12,w19
str w11,[x10,x12]
exit_ins:
ldr x19,[x29,32] //ldr the value of x19 back to the x19
ldp x29, x30, [sp], 64
ret
我做了一些修改,例如在 insertion_loop 函数中加载和存储 n-2 的值,但这并没有做任何改变。
您需要更好地注释您的代码,尤其是当您希望其他人提供帮助时。
我猜测您不是在 w12
中保留 j
,而是用它进行计算,然后尝试取回原始值但失败了。由于您已经完成 add w12,w12,w19
以获得 arr[j+1]
,因此 udiv w12,w12,w19
之后的 w12
的值将是 j+1
并且当您从中减去一个时,您最终得到 j
再次,因此无限循环。您有大量寄存器,只需为 j+1
.
使用不同的寄存器即可
您应该已经能够在调试器中看到这一点。
我正在尝试在汇编 ARMV-8A 中实现插入排序。更具体地说,我试图用 C 翻译以下代码:
void insertionSortRecursive(int arr[], int n)
{
if (n <= 1)
return;
insertionSortRecursive( arr, n-1 );
int last = arr[n-1];
int j = n-2;
while (j >= 0 && arr[j] > last)
{
arr[j+1] = arr[j];
j--;
}
arr[j+1] = last;
}
我试图按原样翻译它,但我的实现在函数 loop_insertion 中进入无限循环,如调试器所示:
.data
my_Table: .space 16
size: .word 4
FileOpenMode: .string "r"
FileName: .string "test1.txt"
fscanf_str: .string "%d"
printf_str: .string "%d "
out_message_str: .string "%d "
.text
.global main
main:
stp x29,x30,[sp,-32]!
add x29,sp,0
adr x1,FileOpenMode
adr x0,FileName
bl fopen
mov x20,x0
adr x0,my_Table
mov x22,x0 //x22 adr of table
mov x21,4
mov x23,0
//**************** READ FROM FILE ******************
loop:
add x2,x29,28
adr x1,fscanf_str
mov x0,x20
bl fscanf
ldr w1,[x29,28]
mov x0,x22
str w1,[x0,x23]
add x23,x23,4
add w21,w21,-1
cbnz w21,loop
//********************************************
mov x0,x22 //adr of table
mov x1,4
bl insertion_sort
//**************** PRINT TO SCREEN FROM TABLE *****************
mov x21,0
mov x23,4
loop_print:
adr x0, out_message_str
ldr w1,[x22,x21]
bl printf
add x21,x21,4
sub x23,x23,1
cbnz x23,loop_print
//***********************************************************
ldp x29, x30, [sp], 32
ret
insertion_sort:
stp x29,x30,[sp,-64]!
add x29,sp,0
str x19,[x29,32] //str the save register
str x0,[x29,16] //str the address of table
str w1,[x29,24] //str the n
mov x19,4
cmp w1,1
b.le exit_ins
sub w1,w1,1
bl insertion_sort
ldr w9,[x29,24] //load the n for the suitable function
sub w9,w9,1 //n-1
mul w9,w9,w19
ldr x10,[x29,16] //adr table
ldr w11,[x10,x9] //last
udiv w9,w9,w19
sub w12,w9,1 //j=n-2
loop_insertion:
ldr w12,[x29,24]
cmp w12,0
b.lt label1
mul w12,w12,w19
ldr w13,[x10,x12] // w13=arr[j]
cmp w13,w11
b.le label1
add w12,w12,w19
str w13,[x10,x12] //arr[j+1]=w13
udiv w12,w12,w19
sub w12,w12,1
str w12,[x29,24]
b loop_insertion
label1:
add w12,w12,1
mul w12,w12,w19
str w11,[x10,x12]
exit_ins:
ldr x19,[x29,32] //ldr the value of x19 back to the x19
ldp x29, x30, [sp], 64
ret
我做了一些修改,例如在 insertion_loop 函数中加载和存储 n-2 的值,但这并没有做任何改变。
您需要更好地注释您的代码,尤其是当您希望其他人提供帮助时。
我猜测您不是在 w12
中保留 j
,而是用它进行计算,然后尝试取回原始值但失败了。由于您已经完成 add w12,w12,w19
以获得 arr[j+1]
,因此 udiv w12,w12,w19
之后的 w12
的值将是 j+1
并且当您从中减去一个时,您最终得到 j
再次,因此无限循环。您有大量寄存器,只需为 j+1
.
您应该已经能够在调试器中看到这一点。