【发布时间】:2015-01-23 11:16:53
【问题描述】:
我正在尝试使用 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,但不清楚为什么数组如下。是分拣问题还是印刷问题?
【问题讨论】:
-
您需要在
print_loop中将指针增加4,因为这是一个双字的大小。实际上,出于同样的原因,在您的代码中最好使用push dword [array+4*esi]。 -
@Jester 谢谢!但是现在输出很奇怪,它没有排序(?)
-
您的评论说
print the unsorted array,确实这就是您正在做的事情......那么您为什么希望它被排序? :) -
@Jester 实际上我确实再次打印了数组,我在这里再次修改了代码以便它适合。输出也更新了。
-
您在排序中至少有与打印中相同的问题,您没有按 4 缩放。除此之外,使用 gdb 单步执行您的代码,看看它在哪里偏离了您的意图。
标签: assembly 32-bit insertion-sort