Jodooomi
Jodooomi

Reputation: 399

Calling conventions -- how to specify them in Assembly? Or are they already implcitly specified?

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

Answers (2)

Flanker
Flanker

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

Frank C.
Frank C.

Reputation: 8088

There are a few points that answer your question:

  • Operating Systems declare a calling convention to use it's services
  • Compilers generate code that accept and call functions based on directives declared as part of the function signature. Some compilers default if no directive says otherwise and some let you pass the directive on invocation of the compiler.
  • Assembly code 'abides' by these various conventions based on what (or who?) they are calling.

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

Related Questions