GNU Info

Info Node: (nasm.info)Section 7.5.1

(nasm.info)Section 7.5.1


Next: Section 7.5.2 Prev: Section 7.5 Up: Section 7.5
Enter node , (file) or (file)node

7.5.1. The Pascal Calling Convention
------------------------------------

   The 16-bit Pascal calling convention is as follows. In the following
description, the words _caller_ and _callee_ are used to denote the
function doing the calling and the function which gets called.

   * The caller pushes the function's parameters on the stack, one after
     another, in normal order (left to right, so that the first argument
     specified to the function is pushed first).

   * The caller then executes a far `CALL' instruction to pass control
     to the callee.

   * The callee receives control, and typically (although this is not
     actually necessary, in functions which do not need to access their
     parameters) starts by saving the value of `SP' in `BP' so as to be
     able to use `BP' as a base pointer to find its parameters on the
     stack.  However, the caller was probably doing this too, so part
     of the calling convention states that `BP' must be preserved by
     any function. Hence the callee, if it is going to set up `BP' as a
     frame pointer, must push the previous value first.

   * The callee may then access its parameters relative to `BP'. The
     word at `[BP]' holds the previous value of `BP' as it was pushed.
     The next word, at `[BP+2]', holds the offset part of the return
     address, and the next one at `[BP+4]' the segment part. The
     parameters begin at `[BP+6]'. The rightmost parameter of the
     function, since it was pushed last, is accessible at this offset
     from `BP'; the others follow, at successively greater offsets.

   * The callee may also wish to decrease `SP' further, so as to
     allocate space on the stack for local variables, which will then
     be accessible at negative offsets from `BP'.

   * The callee, if it wishes to return a value to the caller, should
     leave the value in `AL', `AX' or `DX:AX' depending on the size of
     the value. Floating-point results are returned in `ST0'. Results
     of type `Real' (Borland's own custom floating-point data type, not
     handled directly by the FPU) are returned in `DX:BX:AX'. To return
     a result of type `String', the caller pushes a pointer to a
     temporary string before pushing the parameters, and the callee
     places the returned string value at that location. The pointer is
     not a parameter, and should not be removed from the stack by the
     `RETF' instruction.

   * Once the callee has finished processing, it restores `SP' from
     `BP' if it had allocated local stack space, then pops the previous
     value of `BP', and returns via `RETF'. It uses the form of `RETF'
     with an immediate parameter, giving the number of bytes taken up
     by the parameters on the stack. This causes the parameters to be
     removed from the stack as a side effect of the return instruction.

   * When the caller regains control from the callee, the function
     parameters have already been removed from the stack, so it needs
     to do nothing further.

   Thus, you would define a function in Pascal style, taking two
`Integer'-type parameters, in the following way:

     global  myfunc
     
     myfunc: push    bp
             mov     bp,sp
             sub     sp,0x40         ; 64 bytes of local stack space
             mov     bx,[bp+8]       ; first parameter to function
             mov     bx,[bp+6]       ; second parameter to function
     
             ; some more code
     
             mov     sp,bp           ; undo "sub sp,0x40" above
             pop     bp
             retf    4               ; total size of params is 4

   At the other end of the process, to call a Pascal function from your
assembly code, you would do something like this:

     extern  SomeFunc
     
            ; and then, further down...
     
            push   word seg mystring   ; Now push the segment, and...
            push   word mystring       ; ... offset of "mystring"
            push   word [myint]        ; one of my variables
            call   far SomeFunc

   This is equivalent to the Pascal code

     procedure SomeFunc(String: PChar; Int: Integer);
         SomeFunc(@mystring, myint);


automatically generated by info2www version 1.2.2.9