Created
May 17, 2023 19:34
-
-
Save 0x59R11/a8851a42330ca4e1e47543664e89990c to your computer and use it in GitHub Desktop.
Calling convetions (cdecl, stdcall, fastcall) MSDOS
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.8086 | |
data SEGMENT PARA USE16 PUBLIC 'data' | |
msg DB "Test calling convertions", 24h | |
data ENDS | |
code SEGMENT PARA USE16 PUBLIC 'code' | |
BEGIN: | |
main PROC C | |
mov AX, data | |
mov DS, AX | |
mov DX, offset msg | |
mov AH, 9h | |
int 21h | |
; Cdecl | |
mov AX, 5h | |
push AX | |
mov AX, 10h | |
push AX | |
call add_cdecl | |
add SP, 4h | |
; Stdcall | |
mov AX, 2h | |
push AX | |
mov AX, 0Ah | |
push AX | |
call sub_stdcall | |
; Fastcall | |
mov CX, 0Ah | |
mov DX, 2h | |
call mul_fastcall | |
mov AX, 4C00h | |
int 21h | |
main ENDP | |
; ============================== | |
; cdecl (C declaration): | |
; In the cdecl calling convention, parameters are typically pushed onto the stack from right to left, and the caller is responsible for cleaning up the stack after the function call. Let's assume the function add is called with parameters a = 10 and b = 20. | |
; High Memory Addresses | |
; +------------------+ <- Higher addresses | |
; | | | |
; | Parameter b | | |
; +------------------+ | |
; | | | |
; | Parameter a | | |
; +------------------+ | |
; | | | |
; | Return Address | | |
; +------------------+ | |
; | | | |
; | Base Pointer | | |
; +------------------+ | |
; | | | |
; | (Caller's | | |
; | Local Variables | | |
; | | | |
; +------------------+ | |
; | | | |
; | | | |
; | | | |
; +------------------+ <- Lower addresses | |
; int add_cdecl(int a, int b) | |
add_cdecl PROC C | |
push BP | |
mov BP, SP | |
sub SP, 4h | |
mov AX, WORD PTR [BP + 4] | |
mov DX, WORD PTR [BP + 6] | |
add AX, DX | |
mov SP, BP | |
pop BP | |
ret | |
add_cdecl ENDP | |
; ============================== | |
; stdcall (standard call): | |
; In the stdcall calling convention, parameters are pushed onto the stack from right to left, and the called function is responsible for cleaning up the stack. Let's assume the function add is called with parameters a = 10 and b = 20. | |
; High Memory Addresses | |
; +------------------+ <- Higher addresses | |
; | | | |
; | Parameter b | | |
; +------------------+ | |
; | | | |
; | Parameter a | | |
; +------------------+ | |
; | | | |
; | Return Address | | |
; +------------------+ | |
; | | | |
; | Base Pointer | | |
; +------------------+ | |
; | | | |
; | (Caller's | | |
; | Local Variables | | |
; | | | |
; +------------------+ | |
; | | | |
; | | | |
; | | | |
; +------------------+ <- Lower addresses | |
; int sub_stdcall(int a, int b) | |
sub_stdcall PROC C | |
push BP | |
mov BP, SP | |
sub SP, 4h | |
mov AX, WORD PTR [BP + 4] | |
mov DX, WORD PTR [BP + 6] | |
sub AX, DX | |
mov SP, BP | |
pop BP | |
ret 4 | |
sub_stdcall ENDP | |
; ============================== | |
; In the fastcall calling convention, some parameters are passed in registers, usually ECX and EDX, instead of the stack for optimization purposes. Let's assume the function add is called with parameters a = 10 and b = 20. | |
; High Memory Addresses | |
; +------------------+ <- Higher addresses | |
; | Return Address | | |
; +------------------+ | |
; | Base Pointer | | |
; +------------------+ | |
; | | | |
; | (Caller's | | |
; | Local Variables | | |
; | | | |
; +------------------+ | |
; | | | |
; | | | |
; | | | |
; | | | |
; | | | |
; +------------------+ <- Lower addresses | |
; int mul_fastcall(int a, int b) | |
mul_fastcall PROC C | |
push BP | |
mov BP, SP | |
sub SP, 4h | |
mov AX, CX | |
mul DX | |
mov SP, BP | |
pop BP | |
ret | |
mul_fastcall ENDP | |
code ENDS | |
stack SEGMENT PARA USE16 STACK 'stack' | |
DB 100h DUP(?) | |
stack ENDS | |
END BEGIN |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment