Passing Arguments on the Stack
The programmer must first push the necessary parameters to the subroutine onto the stack. The subroutine then may access each parameter as an offset from BP.
This method is used widely by most of programming languages such as Fortran, C, Pascal, Basic.
There are two important issues must be considered before using stack method:
| The "naming convention" specifies how or if the assembler alters the name of an identifier before placing it into an object file.
| | The "calling convention" determines how the assembler implements a call to a procedure and how the procedure returns to the caller.
|
MASM supports the following different conventions.
Convention | C | SYSCALL | STDCALL | BASIC/FORTRAN/PASCAL
| Leading underscore | X | | X |
| Capitalize all | | | | X
| Arguments pushed left to right | | | | X
| Arguments pushed right to left | X | X | X |
| Caller stack cleanup | X | X | * |
| :VARARG | X | X | X |
|
|
 Naming Conventions |
"Naming convention" refers to the way the assembler stores the names of identifiers. The first two rows of the above Table show how each language type affects symbol names. SYSCALL leaves symbol names as they appear in the source code, but C and STDCALL add an underscore prefix. PASCAL, BASIC, and FORTRAN change symbols to all uppercase.
The following list describes how these naming conventions affect a variable called Big Time in your source code:
Langtype Specified | Characteristics
| SYSCALL | Leaves the name unmodified. The linker sees the variable as Big Time.
| C, STDCALL | The assembler adds a leading underscore to the name, but does not change case.The linker sees the variable as _Big Time.
| PASCAL, FORTRAN, BASIC | Converts all names to uppercase. The linker sees the variable as BIG TIME. |
|
 The C Calling Convention |
Specify the C language type for assembly-language procedures called from programs that assume the C calling convention. Note that such programs are NOT
NECESSARILY WRITTEN IN C, since other languages can mimic C conventions.
With the C calling convention, the caller pushes arguments from right to left as they appear in the caller’s argument list. The called procedure returns without removing the arguments from the stack. It is the caller’s responsibility to clean the stack after the call, either by popping the arguments or by adding an
appropriate value to the stack pointer SP.
|
Suppose you want to implement the following pseudo-code:
i = 25;
| j = 4;
| Test(i, j, 1);
|
Then, the assembly language code fragment looks like:
mov i, 25
| mov j, 4
| push 1
| push _j
| push _i
| call _Test
| add sp, 6
|
As seen above, the rightmost parameter, 1, being pushed first, then _j, and finally _i.
Upon return from a subroutine, the parameters that were pushed on the stack are still there, but are no longer of any use. Consequently, immediately following each subroutine call, the calling code adjusts the stack pointer back to the value it contained before the parameters were pushed, thereby discarding the parameters.
The following figure shows what the stack looks like just before the first instruction in subroutine Test is executed:
Lower Address |
| |
| SP |
| SP+2 |
| SP+4 |
| SP+6 |
| |
| Higher Address |
| |
The subroutine then can access parameters on the stack relative to the BP register.
For example, suppose the subroutine Test in the previous example is:
Example: Accessing parameters on the stack |
_Test PROC
push BP
mov BP, SP
mov AX, [BP + 4] ;get _i
add AX, [BP + 6] ;add _j
sub AX, [BP + 8] ;subtract parm 3 (1) from sum
pop BP
ret
_Test ENDP
|
The following figure shows the state of the stack after PUSH BP and MOV BP, SP are executed.
Lower Address | |
| | |
| SP | | BP
| SP+2 | | BP+2
| SP+4 | | BP+4
| SP+6 | | BP+6
| SP+8 | | BP+8
| | |  
| Higher Address | |  
| |
 The STDCALL Calling Conventions |
Argument passing order for STDCALL is similar as the C calling convention.
| The caller pushes the arguments from right to left.
| | The called procedure cleans the stack if the procedure does not accept a variable number of arguments. Otherwise, the caller must remove the parameters from the stack after the call.
|
Example: Subroutine Test using STDCALL Convention |
_Test PROC
push BP
mov BP, SP
mov AX, [BP + 4] ;get _i
add AX, [BP + 6] ;add _j
sub AX, [BP + 8] ;subtract parm 3 (1) from sum
pop BP
ret 6
_Test ENDP
|
|
 The Pascal Calling Convention |
This convention pushes arguments left to right so that the last argument is lowest on the stack,and it requires that the called subroutines remove arguments from the stack. |
|