CALL (External WinAPI)
Syntax
Syntax: CALL FunctionName(args)
Source: pb_cg_emit_call (pb_codegen.c:4719)
Description
Invokes an external function declared with DECLARE, such as a Windows API or DLL export. The compiler follows the Windows x64 calling convention: the first four integer/pointer arguments go in RCX, RDX, R8, R9; remaining arguments are pushed to the stack. Float arguments go to XMM0-XMM3. BYREF arguments pass a pointer to the variable. String arguments are converted to null-terminated ASCIIZ pointers before the call.
Parameters
| Parameter | Description |
FunctionName | The name of the external function as declared with DECLARE. |
args | Comma-separated list of arguments. Each argument is evaluated and passed according to the Win64 ABI. Use BYVAL or BYREF as specified in the declaration. |
Example
DECLARE FUNCTION MessageBoxA LIB "user32.dll" _
ALIAS "MessageBoxA" ( _
BYVAL hWnd AS QUAD, _
BYVAL lpText AS ASCIIZ PTR, _
BYVAL lpCaption AS ASCIIZ PTR, _
BYVAL uType AS LONG _
) AS LONG
FUNCTION PBMAIN() AS LONG
LOCAL result AS LONG
' Call Windows API MessageBox
CALL MessageBoxA(0, "Hello from PowerBASIC!", _
"PB x64", 0)
FUNCTION = 0
END FUNCTION
Generated Assembly
Integer/Pointer Arguments
; Evaluate each argument -> temp slot
mov [rbp - arg_offset_0], rax ; arg 1 value
mov [rbp - arg_offset_1], rax ; arg 2 value
; ... etc for each arg
; Stage first 4 to registers (Win64 ABI):
mov rcx, [rbp - arg_offset_0] ; arg 1 -> RCX
mov rdx, [rbp - arg_offset_1] ; arg 2 -> RDX
mov r8, [rbp - arg_offset_2] ; arg 3 -> R8
mov r9, [rbp - arg_offset_3] ; arg 4 -> R9
; Stage args 5+ to stack (above shadow space):
mov rax, [rbp - arg_offset_4]
mov [rsp + 32], rax ; arg 5 -> [rsp+32]
mov rax, [rbp - arg_offset_5]
mov [rsp + 40], rax ; arg 6 -> [rsp+40]
; ... offset = 32 + (i-4)*8 ...
call [__imp_<FunctionName>]
Float Arguments
movsd xmm0, [rbp - arg_offset_0] ; FP arg 1 -> XMM0
movsd xmm1, [rbp - arg_offset_1] ; FP arg 2 -> XMM1
movsd xmm2, [rbp - arg_offset_2] ; FP arg 3 -> XMM2
movsd xmm3, [rbp - arg_offset_3] ; FP arg 4 -> XMM3
BYREF Arguments
; Get address of variable (LEA for stack locals)
lea rax, [rbp - var_offset]
mov [rbp - arg_offset], rax ; store address in arg temp
; Then staged normally: mov rcx, [rbp - arg_offset]
STRING Arguments (to ASCIIZ PTR)
; pb_cg_emit_asciiz_pointer -> RAX = null-terminated string pointer
mov [rbp - arg_offset], rax
Win64 Argument Layout
| Arg | Integer/Ptr | Float | Stack (if >4) |
| 1 | RCX | XMM0 | - |
| 2 | RDX | XMM1 | - |
| 3 | R8 | XMM2 | - |
| 4 | R9 | XMM3 | - |
| 5 | [rsp+32] | [rsp+32] | Stack slot 0 |
| 6 | [rsp+40] | [rsp+40] | Stack slot 1 |
| N | [rsp+32+(N-5)*8] | - | Stack slot N-5 |