added some clarification on cdecl16

This commit is contained in:
2024-10-02 10:13:45 -04:00
parent 5e4e40f7de
commit 8e595e8eba

View File

@@ -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