From e057dbdbe30d713664e85d152ccadf8c1041bb5d Mon Sep 17 00:00:00 2001 From: Elaina Claus Date: Wed, 2 Oct 2024 10:13:45 -0400 Subject: [PATCH] added some clarification on cdecl16 --- docs/calling_convention_cdecl16.txt | 104 ++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 docs/calling_convention_cdecl16.txt diff --git a/docs/calling_convention_cdecl16.txt b/docs/calling_convention_cdecl16.txt new file mode 100644 index 0000000..24837b5 --- /dev/null +++ b/docs/calling_convention_cdecl16.txt @@ -0,0 +1,104 @@ +__cdecl16near Calling Convention +Purpose: Used for calling near (within the same segment) functions in 16-bit code. +Stack Management: The caller cleans up the stack after the function call. +Parameter Passing: Parameters are pushed onto the stack from right to left. +Return Address: A near return address (16-bit) is pushed onto the stack. +Return Value: The return value is typically placed in the AX register. + +e.g + +; Caller +push param2 +push param1 +call near_func +add sp, 4 ; Clean up the stack (2 parameters * 2 bytes each) + +; Callee (near_func) +near_func: + push bp + mov bp, sp + ; Function body + mov sp, bp + pop bp + ret + +__cdecl16far Calling Convention +Purpose: Used for calling far (across different segments) functions in 16-bit code. +Stack Management: The caller cleans up the stack after the function call. +Parameter Passing: Parameters are pushed onto the stack from right to left. +Return Address: A far return address (32-bit, consisting of a segment and an offset) is pushed onto the stack. +Return Value: The return value is typically placed in the AX register. + +e.g + +; Caller +push param2 +push param1 +call far_func +add sp, 4 ; Clean up the stack (2 parameters * 2 bytes each) + +; Callee (far_func) +far_func: + push bp + mov bp, sp + ; Function body + mov sp, bp + pop bp + retf ; Far return + +Key Differences +Return Address: __cdecl16near uses a 16-bit return address, while __cdecl16far uses a 32-bit return address (segment:offset). +Function Scope: __cdecl16near is for functions within the same segment, whereas __cdecl16far is for functions that may be in different segments. +Return Instruction: __cdecl16near uses ret, while __cdecl16far uses retf (far return). + + +### REGISTERS ### + +Register Usage in __cdecl16near and __cdecl16far +Caller-Saved Registers (Volatile) +These registers must be saved by the caller if they wish to preserve their values across function calls: + +AX: Accumulator register, often used for return values. +CX: Counter register, commonly used in loops and string operations. +DX: Data register, used for I/O operations and arithmetic. +SI: Source index for string operations. +DI: Destination index for string operations. +Callee-Saved Registers (Non-Volatile) +These registers must be preserved by the callee. If the callee uses these registers, it must save their original values and restore them before returning: + +BP: Base pointer, used for stack frame management. +SP: Stack pointer, although typically managed by the calling convention itself. +BX: Base register, often used for addressing. +SI: Source index, if not used for string operations. +DI: Destination index, if not used for string operations. + +e.g + +; Caller +push param2 +push param1 +call near_func +add sp, 4 ; Clean up the stack (2 parameters * 2 bytes each) + +; Callee (near_func) +near_func: + push bp + mov bp, sp + ; Save callee-saved registers if used + push bx + push si + push di + ; Function body + ; Use AX, CX, DX freely + mov ax, [bp+4] ; Access first parameter + mov bx, [bp+6] ; Access second parameter + ; + ; your other code here + ; + ; Restore callee-saved registers + pop di + pop si + pop bx + mov sp, bp + pop bp + ret