News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

how to make multiple function calls with stack

Started by hellfix, May 25, 2012, 09:59:10 AM

Previous topic - Next topic

hellfix

im trying to call a function with in a function using the stack repeatedly

.listall
.386
.model flat,c
.stack 100h

INCLUDELIB MSVCRT ;used for a vc linking include functions

scanf PROTO arg2:Ptr Byte, inputlist:VARARG
printf PROTO arg1:Ptr Byte, printlist:VARARG

.data
msg1fmt byte 0Ah,"%s",0
msg2fmt byte 0ah,"%d",0
msg1 byte "HELLFIX",0ah,0
sum sdword ?
.code

PUBLIC main

main PROC

  INVOKE printf, ADDR msg1fmt,ADDR msg1
 
  push 6
  push 5
  push 8
  call addNum3
  mov sum,eax
 
  invoke printf,addr msg2fmt, sum
 
  push 4
  push 8
  call addNum2
  mov sum,eax
 
  invoke printf,addr msg2fmt, sum
 
   
main ENDP

addNum2 proc

    push ebp
    mov ebp,esp
    mov eax, [ebp + 12]
    add eax,[ebp + 8]
    pop ebp                   ;restore value it was once before
    ret 8
addNum2 endp

addNum3 proc

       push ebp
       mov ebp,esp
                                         ;im using base offset adddressing
       mov eax,[ebp + 16]       
       mov ebx,[ebp + 12]
       mov ecx,[ebp + 8]
       
       push eax
       push ebx
       push ecx
       
       ;i want to make another function call within a function and place its arguments
       ;on the stack and i want the function to take in parameters off the stack
       ;and calculate a sum
       call reallydosThejob
       add esp, 12                           ;i read this from a book move the return
                                             ;address from the function ontop of the stack
       
       pop ebp
       ret 12                                 ;im not sure if i cleaned up the stack here
addNum3 endp

reallydosThejob proc

                                             ;im guessing it makes nother stack fram on
       push ebp                              ;stack so theres two functions 
       mov ebp,esp
       
       mov eax,[ebp + 16]                    ;get the parameters off the stack does
       mov ebx,[ebp + 12]                    ;what order do they come off the stack
       mov ecx,[ebp + 8]                     ;in this function
       
       add eax,ebx
       add eax,ecx
       
       pop ebp
       ret 12                                  ;im not sure if im doing this right
       
reallydosThejob endp

END main

dedndave

when you use RET 12, you do not need to also use ADD ESP,12
use one or the other
RET 12 returns, and discards 12 bytes from the stack - this is called "StdCall" calling convention
if you just use RET, then the caller adjusts the stack with ADD ESP,12, it's called the "C" calling convention

you do all of this by using PROTO, INVOKE, and letting the assembler take care of the stack frame

MichaelW

The stack adjustment convention is only one part of the calling conventions. The other parts are the order of the arguments on the stack, left to right/right to left, and the naming convention.
Well Microsoft, here's another nice mess you've gotten us into.

dedndave

yes - forgot to mention that

also - i should mention that the API calls use the StdCall calling convention
so - when we write programs in assembly language, we use StdCall
only when we want to mix assembly modules with a C program do we use the C calling convention
even then, it should not be necessary, as the function can be declared as StdCall in the C source

dedndave

here is some code that does not include any API calls - even ExitProcess   :P
if you use StdCall in the .MODEL directive, the assember will use RET 12 to balance the stack
if you use the C calling convention, the assembler will use ADD ESP,12 after the call to balance the stack
it will work either way
Func1   PROTO   :DWORD,:DWORD,:DWORD
Func2   PROTO   :DWORD,:DWORD,:DWORD

        .CODE

Func1   PROC    Parm1:DWORD,Parm2:DWORD,Parm3:DWORD

        INVOKE  Func2,Parm1,Parm2,Parm3
        ret

Func1   ENDP

Func2   PROC    Parm1:DWORD,Parm2:DWORD,Parm3:DWORD

        mov     eax,Parm1
        add     eax,Parm2
        add     eax,Parm3
        ret

Func2   ENDP

Start:  INVOKE  Func1,3,4,5