Kidsm
Kidsm

Reputation: 328

x86 assembly: Output from swap function is incorrect even when the implementation is correct

I've been working on a swap function in order or eventually implement bubble sort using x86 assembly.

My code also includes a function which refactors given number ( from - to + and vise versa ) for another function later, which I've called before testing the swap function

This is the code so far:

org  100h
jmp main

    numToNeg dw -9
    toSwap1 db 'a'
    toSwap2 db 'b'

    param1 equ 8 
    swap1 equ 12
    swap2 equ 14



main: 

    push offset numToNeg
    call refactor

    mov ax, numToNeg
    call print_num     

    PRINTN 

    PRINTN "Before Swap:"

    mov al, toSwap1
    Call print_al_chr ;This function prints the given char inside al
    mov al, toSwap2
    Call print_al_chr 

    push offset toSwap1
    push offset toSwap2

    call swap

    PRINTN

    PRINTN "After Swap:"

    mov al, toSwap1
    Call print_al_chr
    mov al, toSwap2
    Call print_al_chr

PROC refactor 
    push bp
    push bx
    push ax
    mov bp, sp  

    mov bx, [bp + param1] 
    mov ax, [bx]

    not ax
    inc ax 

    mov [bx], ax     

    pop ax
    pop bx
    pop bp
    retn 2

ENDP refactor  

PROC swap 
    push bp
    push ax
    push cx
    push bx
    push di

    mov di, [bp + swap1]
    mov ax, [di]
    mov bx, [bp + swap2]
    mov cx, [bx]
    mov [bx], ax
    mov [di], cx

    pop di
    pop bx
    pop cx
    pop ax
    pop bp
    retn 4
ENDP swap

Now I'm 100% sure that the swap function is correct, so the problem is somewhere in my main function, but I couldn't figure that out by myself. The stack looked alright to me when i debugged the code and I'm pretty stumped right now :/

To be clear, The function "print_al_chr" Is indeed working, and the implementation is inside another file I'm importing each time. At the start I thought that the problem might be with the 'equ' that I was using at the start, but I'm pretty sure that the values I have passed are indeed correct, because that in the function I'm pushing 5 registers, which takes 10 bytes of space overall, so the parameters should be in the 12 and 14 position.

Thanks :D

Edit: The problem was that I was using 16 bit registers instant of 8 bit registers ( AH and CL Instant of AX and CX ), I also forgot to set BP at the start of the function like I did in the refactor function. Thanks everybody for being patient and helpful :D

Upvotes: 2

Views: 194

Answers (1)

ecm
ecm

Reputation: 2763

You are missing a mov bp, sp in this function:

PROC swap 
    push bp
    push ax
    push cx
    push bx
    push di

    mov di, [bp + swap1]

You reserved one byte for each variable:

    toSwap1 db 'a'
    toSwap2 db 'b'

But then you used 16-bit word loads and stores:

    mov di, [bp + swap1]
    mov ax, [di]
    mov bx, [bp + swap2]
    mov cx, [bx]
    mov [bx], ax
    mov [di], cx

As di would point to toSwap1, the last instruction I quoted here would overwrite both variables. (This is what would happen if you had set bp correctly.)


You are missing a program termination call at the end of your main function:

main: 

    push offset numToNeg
    call refactor
[...]
    mov al, toSwap2
    Call print_al_chr

PROC refactor 

If this is indeed for a 86-DOS-compatible system, you should add the following after the last call to print_al_chr:

    mov ax, 4C00h
    int 21h

Another note: The param1, swap1, and swap2 equ's for the stack frame variables could be closer to where these functions that use them are defined. That would make it easier to verify that they are correct.

Upvotes: 6

Related Questions