105 lines
3.1 KiB
Plaintext
105 lines
3.1 KiB
Plaintext
__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
|