1

I have a function "swapByRef" that works in this code (this code just checks if the function swaps the values).

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

But in my code (the bubble sort code) the procedure doesn't swap the values in the array and the array does not get sorted.

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

I've tried to debug and still I couldn't find the problem in my code...
Any help will be awesome, thanks.

Sep Roland
  • 33,889
  • 7
  • 43
  • 76
Yoav Linder
  • 123
  • 1
  • 13
  • 3
    Try to debug better. Also comment your code. Anyway, two problems are immediately visible: `cmp al, ah` makes little sense if your values are in `ax` and `dx`. Furthermore, words are 2 bytes so you should scale the address accordingly. – Jester Jan 14 '18 at 15:28
  • 1
    Writing an actual swap-by-ref function that requires you to pass two addresses makes BubbleSort harder / more complicated to implement in asm. You know the two elements you want to swap are next to each other, because this is BubbleSort, so just do that with offsets from the pointer you're walking through the array and a couple other scratch regs. e.g. this implementation doesn't suck: https://stackoverflow.com/questions/17802947/bubble-sort-in-x86-masm32-the-sort-i-wrote-doesnt-work, and see also https://stackoverflow.com/questions/11497966/assembly-bubble-sort-swap. – Peter Cordes Jan 14 '18 at 16:13

1 Answers1

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

You're adding the offset to the array twice! You need to initialize BX=0.


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

You've read the elements in AX and DX. Then also compare AX and DX.
You can also write it shorter like this:

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

Given that the array contains words and that BX is an offset within the array, you need to change BX in steps of 2. Write add bx, 2 instead of inc bx. This also means that it's best to set len dw 10 and modify it in steps of 2 using sub word ptr len, 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

Your swapByRef proc destroys a lot of registers. Especially loosing BX is problematic!
This is a general solution to not clobber registers. Optimize as needed.

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
Sep Roland
  • 33,889
  • 7
  • 43
  • 76