Reputation: 399
Algthouh I've been reading about calling conventions and I know what they are, I've not found any mention about which plathorms use which calling conventions or is it what a programmer has to explicitly setup by some directive to the assembly compiler. In other words, how to set them up explicitly.
Will anyone help me understand? Or are there any default calling conventions for certain plathorms and assembly compilers? Or .... how does that work in general?
Upvotes: 0
Views: 1231
Reputation: 408
Old MS-DOS MASM (x86 real mode), to use C function / calling convention:
printf PROTO arg1:Ptr Byte, printlist: VARARG
;The first argument is a pointer to a string. The second is a keyword
; that permits a variable number of arguments.
.STACK 100h
.DATA
fmtlist BYTE "%s, %d, %lu", 0Ah,0
string_1 BYTE "signed byte and unsigned double word", 0
data_1 SBYTE -2
data_2 DWORD 0FFFFFFFFh
.CODE
main PROC
INVOKE printf, ADDR fmtlist, ADDR string_1, data_1, data_2
main ENDP
ret
end
Then MASM puts the arguments and return address (IP), also SP frame into stack in correct order (IIRC there were some differences between C and Pascal modules).
Back to 2017, here is Overview of x64 Calling Conventions, also Parameter Passing (Windows).
The x64 Application Binary Interface (ABI) uses a four register fast-call calling convention by default...There is a strict one-to-one correspondence between the arguments to a function call and the registers used for those arguments. Any argument that doesn’t fit in 8 bytes, or is not 1, 2, 4, or 8 bytes, must be passed by reference. There is no attempt to spread a single argument across multiple registers...
Integer values are passed in RCX, RDX, R8, and R9... floating point - XMM0 – XMM3, others passed on the stack.
Some sample Windows x64 asm here.
Upvotes: 0
Reputation: 8088
There are a few points that answer your question:
However; in a pure assembly program, the code in assembly can call itself using just about any protocol it wants to define. For example:
bar:
add rdi, rsi
mov rax, rdi
ret
foo:
mov rdi, arg1
mov rsi, arg2
call bar
ret
follows a convention where the caller foo
passes arguments in registers RDI, RSI as the order the callee is expecting. This is a familiar convention for System V (linux, mac, etc.).
But because I am not calling any OS or libraries I am free to change the above to:
bar:
add r11, r12
mov r13, r11
ret
foo:
mov r11, arg1
mov r12, arg2
call bar
ret
I could also use a stack based convention for passing arguments. One thing to be aware of when using your own convention is any considerations that the OS may impose. These are readily understood by grabbing yourself a copy of the target OS ABI document.
Upvotes: 2