我想在汇编中进行冒泡,我不明白它为什么不起作用

时间:2018-01-14 15:23:54

标签: sorting assembly x86-16 bubble-sort

我有一个功能" swapByRef"适用于此代码(此代码仅检查函数是否交换值)。

MODEL small
STACK 10h
DATA SEGMENT
a dw 12h
b dw 0A9h
DATA ENDS
CODE SEGMENT
    ASSUME CS:CODE, DS:DATA
start:
    mov ax, DATA
    mov ds, ax
    push offset a ;push to the stack the adress of the variable a
    push offset b ;push to the stack the adress of the variable b
    call swapByRef  
exit:
    mov ax, 4c00h
    int 21h
swapByRef proc
    mov bp, sp
    mov bx, [bp + 2]
    mov ax, [bx]
    mov si, [bp + 4]
    mov cx, [si]
    mov [bx], cx
    mov[si], ax
    ret 4
swapByRef endP
CODE ENDS
END start

但是在我的代码(冒泡排序代码)中,该过程不会交换数组中的值,并且数组不会被排序。

MODEL small
STACK 100h
DATA SEGMENT
ARR dw 9,5,7,3,8
len dw 5
DATA ENDS
CODE SEGMENT
    ASSUME CS:CODE, DS:DATA
start:
    mov ax, DATA
    mov ds, ax

    mov bx, offset ARR
sorting:
    mov ax, len
    dec ax
    cmp bx, ax
    je redo
    mov ax, ARR[bx]
    mov dx, ARR[bx+ 2]
    cmp al, ah
    jg swap
    jmp continue
swap:
    push offset [ARR + bx]
    push offset [ARR + bx + 2]
    call swapByRef
continue:
    inc bx
    jmp sorting
redo:
    cmp len, 0
    je exit
    mov ax, len
    dec ax
    mov len, ax
    xor bl, bl
    jmp sorting
exit:
    mov ax, 4c00h
    int 21h

    swapByRef proc
    mov bp, sp
    mov bx, [bp + 2]
    mov ax, [bx]
    mov si, [bp + 4]
    mov cx, [si]
    mov [bx], cx
    mov[si], ax
    ret 4
swapByRef endP
CODE ENDS
END start

我已尝试调试但仍无法在代码中找到问题...
任何帮助都会很棒,谢谢。

1 个答案:

答案 0 :(得分:3)

mov bx, offset ARR
...
mov ax, ARR[bx]
mov dx, ARR[bx+ 2]

您将数据的偏移量添加两次!您需要初始化BX=0

 mov ax, ARR[bx]
 mov dx, ARR[bx+ 2]
 cmp al, ah
 jg swap
 jmp continue
swap:

您已阅读AXDX中的元素。然后还要比较AXDX 您也可以将它写得更短:

    mov ax, ARR[bx]
    cmp ax, ARR[bx+2]
    jng continue
swap:

鉴于数组包含单词BX是数组中的偏移量,您需要以2为步骤更改BX。编写add bx, 2而不是inc bx。 这也意味着最好设置len dw 10并使用sub word ptr len, 2以2为步进对其进行修改。

swapByRef proc
mov bp, sp
mov bx, [bp + 2]
mov ax, [bx]
mov si, [bp + 4]
mov cx, [si]
mov [bx], cx
mov[si], ax
ret 4

你的 swapByRef proc会破坏很多寄存器。特别是失去BX是有问题的! 这是不是clobber寄存器的一般解决方案。根据需要进行优化。

swapByRef proc
    push bp
    mov  bp, sp
    push ax
    push bx
    push cx
    push si
    mov  bx, [bp + 4]
    mov  ax, [bx]
    mov  si, [bp + 6]
    mov  cx, [si]
    mov  [bx], cx
    mov  [si], ax
    pop  si
    pop  cx
    pop  bx
    pop  ax
    pop  bp
    ret  4