Retro video games delivered to your door every month!
Click above to get retro games delivered to your door ever month!
X-Hacker.org- Watcom C/C++ User's Guide - consider the following example. http://www.X-Hacker.org [<<Previous Entry] [^^Up^^] [Next Entry>>] [Menu] [About The Guide]
Consider the following example.

Example:

     void main()
     {
         double   x;
         int      i;
         double   y;

         x = 7;
         i = 77;
         y = 777;
         myrtn( x, i, y );
     }

myrtn is an assembly language function that requires three arguments.  The
first argument is of type "double", the second argument is of type "int" and
the third argument is again of type "double".  Using the rules for
register-based calling conventions, these arguments will be passed to myrtn
in the following way:

 1. The first argument will be passed in registers EDX and EAX leaving EBX
    and ECX as available registers for other arguments.

 2. The second argument will be passed in register EBX leaving ECX as an
    available register for other arguments.

 3. The third argument will not fit in register ECX (its size is 8 bytes)
    and hence will be pushed on the stack.

Let us look at the stack upon entry to myrtn.


     Small Code Model
     Offset
             +----------------+
       0     | return address | <- ESP points here
             +----------------+
       4     | argument #3    |
             |                |
             +----------------+
      12     |                |


     Big Code Model
     Offset
             +----------------+
       0     | return address | <- ESP points here
             |                |
             +----------------+
       8     | argument #3    |
             |                |
             +----------------+
      16     |                |

Notes:

 1. The return address is the top element on the stack.  In a small code
    model, the return address is 1 double word (32 bits)

Register EBP is normally used to address arguments on the stack.  Upon entry
to the function, register EBP is set to point to the stack but before doing
so we must save its contents.  The following two instructions achieve this.


     push    EBP           ; save current value of EBP
     mov     EBP,ESP       ; get access to arguments

After executing these instructions, the stack looks like this.


     Small Code Model
     Offset
             +----------------+
       0     | saved EBP      | <- EBP and ESP point here
             +----------------+
       4     | return address |
             +----------------+
       8     | argument #3    |
             |                |
             +----------------+
      16     |                |


     Big Code Model
     Offset
             +----------------+
       0     | saved EBP      | <- EBP and ESP point here
             +----------------+
       4     | return address |
             |                |
             +----------------+
      12     | argument #3    |
             |                |
             +----------------+
      20     |                |

As the above diagrams show, the third argument is at offset 8 from register
EBP in a small code model and offset 12 in a big code model.

Upon exit from myrtn, we must restore the value of EBP.  The following two
instructions achieve this.


     mov     ESP,EBP       ; restore stack pointer
     pop     EBP           ; restore EBP

The following is a sample assembly language function which implements myrtn.


     Small Memory Model (small code, small data)
     DGROUP        group   _DATA, _BSS
     _TEXT         segment byte public 'CODE'
                   assume  CS:_TEXT
                   assume  DS:DGROUP
                   public  myrtn_
     myrtn_        proc    near
                   push    EBP
                   ; save EBP
                   mov     EBP,ESP   ; get access to arguments
     ;
     ; body of function
     ;
                   mov     ESP,EBP   ; restore ESP
                   pop     EBP
                   ; restore EBP
                   ret     8         ; return and pop last arg
     myrtn_        endp
     _TEXT         ends


     Large Memory Model (big code, big data)
     DGROUP        group   _DATA, _BSS
     MYRTN_TEXT segment byte public 'CODE'
                   assume  CS:MYRTN_TEXT
                   public  myrtn_
     myrtn_        proc    far
                   push    EBP
                   ; save EBP
                   mov     EBP,ESP   ; get access to arguments
     ;
     ; body of function
     ;
                   mov     ESP,EBP   ; restore ESP
                   pop     EBP
                   ; restore EBP
                   ret     8         ; return and pop last arg
     myrtn_        endp
     MYRTN_TEXT ends

Notes:

 1. Global function names must be followed with an underscore.  Global
    variable names must be preceded with an underscore.

 2. All used 80x86 registers must be saved on entry and restored on exit
    except those used to pass arguments and return values.  Note that
    segment registers only have to saved and restored if you are compiling
    your application with the "r" option.

 3. The direction flag must be clear before returning to the caller.

 4. In a small code model, any segment containing executable code must
    belong to the segment "_TEXT" and the class "CODE".  The segment "_TEXT"
    must have a "combine" type of "PUBLIC".  On entry, CS contains the
    segment address of the segment "_TEXT".  In a big code model there is no
    restriction on the naming of segments which contain executable code.

 5. In a small data model, segment register DS contains the segment address
    of the group "DGROUP".  This is not the case in a big data model.

 6. When writing assembly language functions for the small code model, you
    must declare them as "near".  If you wish to write assembly language
    functions for the big code model, you must declare them as "far".

 7. In general, when naming segments for your code or data, you should
    follow the conventions described in the section entitled "Memory Layout"
    in this chapter.

 8. If any of the arguments was pushed onto the stack, the called routine
    must pop those arguments off the stack in the "ret" instruction.

Online resources provided by: http://www.X-Hacker.org --- NG 2 HTML conversion by Dave Pearson