|
In mixed language programming, most of the time you would call an assembler routine from a high level language. However you can still call Basic code from C or visa versa. In this article, I will explain how to call assembler routines from Basic, C, and Pascal. If you would like to know how to call a high level language from another high level language, send us some mail.
Assembler from Basic, C, or Pascal:
Basic and Pascal by default pushes the parameters on the stack in forward order. i.e.: Pushes Parm1 then Parm2 then etc.. C, however, pushes then in backward order. Parm4, Parm3, Parm2, and Parm1.
Basic pushes a near address of size WORD (2 bytes) for each parameter. C and Pascal push the value of each parameter. Then each push the return address with Basic, Pascal, and C (in medium or larger) pushing a far address (4 bytes) and C (small) pushing a near address (2 bytes). Finally, each push a copy of the BP register.
Here is a stack frame after an assembler call is made for each high level language (Remember that the stack grows down for each push and up for each pop):
Basic |
C |
Pascal |
Arg 1 address (BP + 8) |
Arg 2 address (BP + 6) |
Arg 1 address (BP + 8) |
Arg 2 address (BP + 6) |
Arg 1 address (BP + 4) |
Arg 2 address (BP + 6) |
Return address (BP + 4) |
Return address (BP + 2) |
Return address (BP + 4) |
Saved BP (BP + 0) |
Saved BP (BP + 0) |
Saved BP (BP + 0) |
Basic uses the MEDIUM model, Pascal uses the LARGE model, and C uses whatever model the C source is using, when calling the assembler routine.
Basic:
'The basic code
DECLARE FUNCTION ProcName%
(parm1 as interger, parm2 as interger)
RC% = ProcName%(parm1%, Parm2%)
; the assembler code
.MODEL Medium
.CODE
PUBLIC ProcName
ProcName PROC
push bp
mov bp,sp
mov bx,[bp+8] ; pushed near pointers.
mov ax,[bx] ; first parameter
mov bx,[bp+6] ;
mov dx,[bx] ; second parameter
.... do something with them
; if a FUNCTION then Basic uses dx:ax as RC
pop bp
ret 4 ; 4 = bytes used in params
; 2 parms of 2 bytes each
ProcName ENDP
END
|
C:
/* The C code */
extern int ProcName(int, int);
main() {
printf("The RC = %i", ProcName(parm1,parm2));
}
; the assembler code
.MODEL Small
.CODE
PUBLIC ProcName
ProcName PROC
push bp
mov bp,sp
mov ax,[bp+4] ; first parameter
mov dx,[bp+6] ; second parameter
.... do something with them
; C uses dx:ax as RC
pop bp
ret
ProcName ENDP
END
Pascal:
{Here is the Pascal code}
program demo;
function ProcName(parm1,parm2:integer):integer; extern;
begin
writeln('The RC = ',ProcName(parm1,parm2));
end.
; the assembler code
.MODEL Large
.CODE
PUBLIC ProcName
ProcName PROC
push bp
mov bp,sp
mov ax,[bp+8] ; first parameter
mov dx,[bp+6] ; second parameter
.... do something with them
; if a function then Pascal uses dx:ax as RC
pop bp
ret 4
ProcName ENDP
END
If you have any questions, please let us know.
¥
|