我尝试使用NASM在Linux中的32位程序集中实现插入排序,但出了点问题。 这是代码:
section .rodata
MSG: DB "welcome to sortMe, please sort me",10,0
S1: DB "%d",10,0 ; 10 = '\n' , 0 = '\0'
section .data
array DD 5,1,7,3,4,9,12,8,10,2,6,11 ; unsorted array
len DB 12
section .text
align 16
global main
extern printf
main:
push MSG ; print welcome message
call printf
add esp,4 ; clean the stack
call printArray ;print the unsorted array
;parameters
;push len
;push array
mov eax, len
mov ebx, array
push eax
push ebx
call myInsertionSort
call printArray
mov eax, 1 ;exit system call
int 0x80
printArray:
push ebp ;save old frame pointer
mov ebp,esp ;create new frame on stack
pusha ;save registers
mov eax,0
mov ebx,0
mov edi,0
mov esi,0 ;array index
mov bl, byte [len]
add edi,ebx ; edi = array size
print_loop:
cmp esi,edi
je print_end
push dword [array+4*esi]
push S1
call printf
add esp, 8 ;clean the stack
inc esi
jmp print_loop
print_end:
popa ;restore registers
mov esp,ebp ;clean the stack frame
pop ebp ;return to old stack frame
ret
myInsertionSort:
push ebp
mov ebp, esp
push ebx
push esi
push edi
mov ecx, [ebp+12]
movzx ecx, byte [ecx] ;put len in ecx, our loop variable
mov eax, 4 ; size of one spot in array, one byte
mov ebx, 0
mov esi, [ebp+8] ; the array
loop loop_1
loop_1:
cmp eax, ecx ; if we're done
jge done_1 ; then done with loop
push ecx ; we save len, because loop command decrements ecx
mov ecx, [esi+eax] ; ecx now array[i]
mov ebx, eax
shr ebx, 2 ; number of times for inner loop
loop_2:
cmp ebx, 0 ; we don't use loop to not affect ecx so we use ebx and compare it manually with 0
jl done_2
cmp [esi+ebx], ecx ;we see if array[ebx] os ecx so we can exit the loop
jle done_2
lea edx, [esi+ebx]
push dword [edx] ; pushing our array[ebx]
add edx, eax
pop dword [edx] ; poping the last one
dec ebx ; decrementing the loop iterator
jmp loop_2 ; looping again
done_2:
mov [esi+ebx+1], ecx
inc eax ; incrementing iterator
pop ecx ; len of array to compare now to eax and see if we're done
jmp loop_1
done_1:
pop edi
pop esi
pop ebx
pop ebp ; we pop them in opposite to how we pushed
ret
该计划的输出是:
welcome to sortMe, please sort me
5
1
7
3
4
9
12
8
10
2
6
11
到目前为止它是未排序的数组,然后程序输出:
327681
1280
0
5
4
9
12
8
10
2
6
11
任何线索为什么会发生这种情况?问题出在哪儿?我经历了gdb
,但不清楚为什么数组如下。排序或打印有问题吗?
答案 0 :(得分:0)
在你call myInsertionSort
之后,你仍然需要用add esp,8
清理堆栈!
退出系统调用也使用EBX。
排序或打印有问题吗?打印工作正常,但您可以稍微清理一下代码。
没有必要使用经典的prolog / epilog,清除EAX也没用。
在 printArray 中pusha/popa
更改pushad/popad
。
我认为 myInsertionSort 的代码是无法实现的。这是我的插入排序版本:
myInsertionSort:
pushad ;This uses 32 bytes on the stack
mov ebp,esp
mov ebx,[ebp+32+4] ;Address of array
mov ecx,[ebp+32+8] ;Address of len
movzx ecx,byte [ecx] ;len
sub ecx,1
jbe .exit ;Nothing to sort
xor edi,edi ;Index of candidate
.start:
inc edi
mov eax,[ebx+edi*4] ;Value of candidate
xor esi,esi ;Index within the underlying elements
.find:
cmp [ebx+esi*4],eax
jg .insert
add esi,1
cmp esi,edi
jb .find
jmps .next ;No insertion needed
.insert:
xchg [ebx+esi*4],eax
add esi,1
cmp esi,edi
jb .insert
mov [ebx+esi*4],eax
.next:
cmp edi,ecx
jb .start
.exit:
popad
ret