Assembler Programming Lecture 10
Lecture 10 Mixed language programming. C and Basic to MASM Interface.
Mixed language programming Combine Basic, C, Pascal with assembler. Call MASM routines from HLL program. Call HLL routines from assembler program. MASM provides some mixed language features.
Mixed language programming *.c *.asm compiler assembler *.obj *.obj linker *.exe
Language option.model directive language option PASCAL BASIC FORTRAN C SYSCALL STDCALL INVOKE, PROC, PUBLIC and EXTERN use the naming and calling convention of specified language.
Naming and calling convention naming convention specifies how the compiler alters the name of an identifier before placing it into an object file. calling convention determines how a language implements a call to a procedure and how the procedure returns to the caller.
Naming convention How the assembler stores the names of identifiers. SYSCALL does not change the symbols, C, STDCALL add an underscore prefix, PASCAL, BASIC, FORTRAN change symbols to uppercase.
Naming convention Symbol: Variable SYSCALL Variable C _Variable STDCALL _Variable PASCAL VARIABLE BASIC VARIABLE FORTRAN VARIABLE
C calling convention Argument passing pushed from right to left caller cleans the stack after the call Register preservation subroutine must preserve BP, SI, DI, DS, SS and direction flag Varying number of arguments first argument in the list is always on the top of the stack
Pascal calling convention Argument passing pushed from left to right as they appear in the source code called routine cleans the stack before return Register preservation subroutine must preserve BP, SI, DI, DS, SS and direction flag Varying number of arguments not possible in Pascal calling convention
SYSCALL calling convention Argument passing pushed from right to left caller cleans the stack after the call Register preservation subroutine must preserve BP, SI, DI, DS, SS Varying number of arguments first argument in the list is always on the top of the stack
STDCALL calling convention Argument passing pushed from right to left if procedure accepts variable number of parameters caller cleans the stack after the call, otherwise procedure cleans the stack. Register preservation subroutine must preserve PB, SI, DI, DS, SS direction flag must be returned clear Varying number of arguments allowed for procedures declared with VARARG
Conventions summarize Convention C SYSCALL STDCALL BASIC FORTRAN PASCAL Leading underscore Capitalize all Arguments pushed left to right Arguments pushed right to left Caller stack cleanup * VARARG allowed
MASM features PROTO directive improves error checking on argument types. INVOKE pushes arguments onto the stack and converts argument types. LOCAL following the PROC saves places on the stack for local variables. PROC sets up the appropriate stack frame. USES keyword preserves registers. RET keyword adjusts the stack.
The C/MASM interface - data types C Type unsigned char Char unsigned short, unsigned int int, short unsigned long Long Float Double long double MASM Type BYTE SBYTE WORD SWORD DWORD SDWORD REAL4 REAL8 REAL10
C/MASM Interface Naming restrictions C is case sensitive, does not convert names to uppercase. You should assemble MASM modules with /Cx or /Cp option. Arguments passing C passes: arrays by reference, other variables by value. To pass variable as reference use the address operator (&)
C/MASM Interface Array storage arrays are stored in row-major order for example the first five elements of an array with four rows and three columns are stored as: A[1, 1], A[1, 2], A[1, 3], A[2, 1], A[2, 2] String format stored as arrays of bytes uses null character as the delimiter
Returning values C/MASM Interface simple data types in registers: AL, AX, EAX, DX:AX or EDX:EAX float and double in static variables structures less than 4 bytes in DX:AX structures longer than 4 bytes - copy to global variable and return pointer in AX Compiling and Linking Use the same memory model for both C and MASM.
C/MASM - Example #include <stdio.h> extern extern int int Power2( int int factor, int int power power ); ); void void main() main() { printf("3 times times 2 to to the the power power of of 5 is is %d\n", %d\n", Power2(3, 5)); 5)); }.MODEL.MODEL small, small, c Power2 Power2 PROTO PROTO C factor:sword, power:sword.code.code Power2 Power2 PROC PROC C factor:sword, power:sword mov mov ax, ax, factor factor ; Load Load Arg1 Arg1 into into AX AX mov mov cx, cx, power power ; Load Load Arg2 Arg2 into into CX CX shl shl ax, ax, cl cl ; AX AX = AX AX * (2 (2 to to power power of of CX) CX) ; Leave Leave return return value value in in AX AX ret ret Power2 Power2 ENDP ENDP END END
Basic/MASM interface - data types C Type STRING*1 INTEGER (X%) LONG (X&), CURRENCY SINGLE (X!) DOUBLE (X#) MASM Type WORD SWORD SDWORD REAL4 REAL8
Basic/MASM Interface Naming restrictions Basic recognizes up to 40 characters. Basic drops %, &,!, #, @ Array storage arrays are stored in column-major order for example the first five elements of an array defined with DIM Arr%(3,3) are: Arr(0, 0), Arr(1, 0), Arr(2, 0), Arr(0, 1), Arr(1, 1)
Basic/MASM Interface Arguments passing Basic passes: by near reference (2-byte address) Use DECLARE statement to change arguments passing: to pass variable by far reference use SEG, to pass variable by value use BYVAL, You cannot pass arrays and user types by value.
Basic/MASM - Example DECLARE SUB Test(BYVAL a%, b%, SEG c%) DECLARE SUB Test2(a%, b%, c%) CALL Test(x%, y%, z%) CALLS Test(x%, y%, z%) CALLS Test2(x%, y%, z%)
String format Basic/MASM Interface Basic maintains 4-byte string descriptor first 2-byte filed indicates the length of the string second field contains the offset address DESC STRUCT len len WORD? ; Length of of string off off WORD? ; Offset of of string DESC ENDS string BYTE "Text referenced by by a descriptor" sdesc DESC (LENGTHOF string, string)
Basic/MASM Interface Returning values 2-byte integers in AX 4-byte integers in DX:AX all other types as near offset in AX Compiling and Linking Always use medium model in assembly-language procedures linked with Basic modules.
Basic/MASM - Example DEFINT DEFINT A-Z A-Z DECLARE FUNCTION Power2 Power2 (A (A AS AS INTEGER, B AS AS INTEGER) PRINT PRINT "3 "3 times times 2 to to the the power power of of 5 is is "; "; PRINT PRINT Power2(3, 5) 5) END END.MODEL.MODEL medium medium Power2 Power2 PROTO PROTO PASCAL, factor:ptr WORD, WORD, power:ptr WORD WORD.CODE.CODE Power2 Power2 PROC PROC PASCAL, factor:ptr WORD, WORD, power:ptr WORD WORD mov mov bx, bx, WORD WORD PTR PTR factor factor ; BX BX points points to to factor factor mov mov ax, ax, [bx] [bx] ; Load Load factor factor into into AX AX mov mov bx, bx, WORD WORD PTR PTR power power ; BX BX points points to to power power mov mov cx, cx, [bx] [bx] ; Load Load power power into into CX CX shl shl ax, ax, cl cl ; AX AX = AX AX * (2 (2 to to power power of of CX) CX) ret ret Power2 Power2 ENDP ENDP END END
Example 1 /* /* Example to to illustrate C and and assembly language interface. The The test test function is is written in in assembler */ */ #include <stdio.h> int int main main (void) (void) { int int x=25, x=25, y=70; y=70; int int value; value; extern extern int int test(int, int, int, int); int); } value value = test test (x, (x, y, y, 5); 5); printf printf ( result= %d\n, %d\n, value); return return 0; 0;
Example 1 ; Assembly program for for the the test test function ; called called from from the the C program.model.model SMALL SMALL.CODE.CODE PUBLIC PUBLIC _test _test _test _test PROC PROC push push BP BP mov mov BP, BP, SP SP mov mov AX, AX, [BP4] [BP4] ; get get argument1 (x) (x) add add AX, AX, [BP6] [BP6] ; add add argument2 (y) (y) sub sub AX, AX, [BP8] [BP8] ; substract argument3 (5) (5) from from sum sum pop pop BP BP ret ret ; stack stack is is cleared by by the the C function _test _test ENDP ENDP END END
Example 2 /* /* A string string processing example to to illustrate global global variables. The The string_length function is is written in in assembler */ */ #include <stdio.h> #define LENGTH LENGTH 256 256 char char string[length]; int int main main (void) (void) { extern extern int int string_length (char (char a[]); a[]); } printf printf ( Enter string: ); ); scanf scanf ( %s, ( %s, string); printf printf ( string length= %d\n, %d\n, string_length()); return return 0; 0;
Example 2 ; string_length function works works on on the the global global variable ; defined in in the the C program.model.model SMALL SMALL.DATA.DATA EXTRN EXTRN _string:byte.code.code PUBLIC PUBLIC _string_length _string_length PROC PROC mov mov AX, AX, 0 ; AX AX keeps keeps the the character count count mov mov BX, BX, OFFSET OFFSET _string ; load load BX BX with with string string address repeat1: cmp cmp BYTE BYTE PTR PTR [BX], [BX], 0 ; load load with with NULL NULL character jz jz done done inc inc AX AX ; increment string string length length inc inc BX BX ; inc inc BX BX to to point point to to next next char char jmp jmp repeat1 done: done: ret ret ; stack stack is is cleared by by the the C _string_length ENDP ENDP END END