Search code examples
assemblymasmmasm32

Passing a parameter via stack to procedure in MASM


I am trying to pass 3 parameters to a procedure, add them, and return them in tax register in MASM. However, the result is off with a random huge number. I am trying to use the C style calling convention where I am passing 3 variables to a function. What am I doing wrong? Here is my code:

INCLUDE PCMAC.INC


.MODEL SMALL
.586
.STACK 100h
.DATA

.CODE
        EXTRN  GetDec :NEAR, PutDDec : NEAR, PutHex : NEAR
Main PROC
        _Begin
        push 10
        push 20
        push 30

        call Test1


        call PutDDec
        add esp, 12

        _Exit
Main ENDP
Test1 PROC
    ; *** Standard subroutine prologue ***
    push ebp
    mov ebp, esp
    sub esp, 4
    push edi
    push esi

    ; *** Subroutine Body ***

    mov eax, [ebp+8] ; parameter 1 / character
    mov esi, [ebp+12] ; parameter 2 / width
    mov edi, [ebp+16] ; parameter 3 / height

    mov [ebp-4], edi
    add [ebp-4], esi
    add eax, [ebp-8]
    add eax, [ebp-4]

    ; *** Standard subroutine epilogue ***
    pop esi ; Recover register values
    pop edi
    mov esp, ebp ; Deallocate local variables
    pop ebp ; Restore the caller’s base pointer value

    ret
Test1 ENDP
End Main

Solution

  • What am I doing wrong?

    You did not comment your code and you did not use a debugger.

    mov [ebp-4], edi
    add [ebp-4], esi
    add eax, [ebp-8] ; <---- what is this ebp-8 here?
    add eax, [ebp-4]
    

    To add 3 numbers you only need 2 additions, why do you have 3? Also you don't even need to use a local variable, you can just do:

    push ebp
    mov ebp, esp
    
    mov eax, [ebp+8] ; parameter 1 / character
    add eax, [ebp+12] ; parameter 2 / width
    add eax, [ebp+16] ; parameter 3 / height
    
    mov esp, ebp ; Deallocate local variables
    pop ebp ; Restore the caller’s base pointer value
    
    ret
    

    Or, if you don't need the stack frame then just:

    mov eax, [esp+4]
    add eax, [esp+8]
    add eax, [esp+12]
    ret