对汇编8086 16位的数组进行排序



我试图通过使用在数组中找到最小数字的函数对数组进行排序,而其他函数交换两个变量。但由于某些原因,数组没有改变,保持不变。我想我的堆栈有问题,但我找不到它。

这是我的代码:抱歉它很长而且没有组织。我刚开始组装。'

org 100h

jmp start
array db 1,9,3,6,3 **;should get 1,2,3,6,9**
min_in_array dw ?

start: 

lea si, array         
push 5 
push si
call sortArray 
pop bx
pop bx
mov ah, 0
int 16h
ret

;doesn't work
PROC sortArray
push bp
mov bp, sp

mov dx, 0 ;the index
mov cx, [bp+6];size
mov di, [bp+4];array  

loop_arr: 
add di, dx
push di
call findMin
pop di


sub di, dx

add di, min_in_array 
push dx        
push di
call swap
pop di
pop dx
sub di, min_in_array
inc dx

mov ax, [di]
loop loop_arr


mov sp, bp
pop bp

ret
ENDP sortArray    

;works
PROC findMin
push bp
mov bp, sp
sub sp, 4

mov cx, 0 ;init the counter
mov di, [bp+4]
mov al, [bp-2] ;initialising the min save var
mov al, [di] 

mov bx, [bp-4] ;the index to save
mov bx, 0

run:
cmp al, [di] 
ja change_min 
cmp cx, 4 ;check if cx is lower than the size of the array
inc cx ;+1
inc di ;move forward in the array
jb run ;check again
jmp fin ;finished - cx = size

change_min:        
mov al, [di] ;change the min
mov bx, cx  ;assign the index
inc di 
cmp cx, 4  
je fin
inc cx
jmp run


fin: 
mov sp, bp
pop bp
mov cx, 0

mov min_in_array, bx
ret 
ENDP findMin                               

;function works
PROC swap       
;creates fram  
push    bp
mov     bp,sp  

sub sp,2 ;make space for local temp 
mov bx, [bp+6]
mov cx, [bp+4]
;swaping using the temp varaiable
mov [bp-2], bx
mov bx, cx
mov cx, [bp-2]

;close frame
mov sp, bp
pop bp
ret
ENDP swap  

我有一个问题与堆栈,但我找不到它。

你对堆栈的使用实际上是好的:序言,尾声,清理。
但是堆栈还擅长一件事,那就是保存寄存器值。你的sortArray过程依赖于CX寄存器,但是你在findMinswap过程中销毁了它的值!

你说findMin工作,但我向你保证它没有。除了不保留CX和包含大量未使用的代码之外,findMin总是处理5个元素,即使提供的地址随着每次调用而上移,这意味着您正在处理内存中原始数组之后的垃圾。此外,存储在min_in_array变量中的结果是数组未排序分区中的偏移量,但是在返回后,sortArray将使用与原始数组中的偏移量相同的值。不能那样工作…

你说swap行得通,但我向你保证它行不通。您向该过程提供的是原始数组中的偏移量和原始数组中的(错误计算的)地址。你从堆栈中获取这些参数,只在寄存器中交换它们,仅此而已。你从来没有在数组中读/写,所以没有交换发生。

看看下一段代码是否为你指明了正确的方向:

add  di, dx
push cx         ; Number of elements in the unsorted partition
push di         ; Address of the start of the unsorted partition
call findMin    ; -> AX (BL CX SI)
pop  di
pop  cx
push ax         ; Address of the Min from the unsorted partition
push di         ; Address of the start of the unsorted partition
call swap
...
; IN () OUT (ax) MOD (bl,cx,si)
PROC findMin
push bp
mov  bp, sp
mov  cx, [bp + 6]
mov  si, [bp + 4]
min:
mov  bl, [si] 
mov  ax, si
run:
dec  cx
jz   done
inc  si
cmp  bl, [si] 
jb   run
jmp  min                 ; Go change min
done:
pop  bp
ret 
ENDP findMin

最新更新