<--- Turn the page     (contents page)     Turn the page --->


Mixed-Language Programming




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. ¥



<--- Turn the page     (contents page)     Turn the page --->

Page 14