Inline Assembly and how to call functions

Sometimes, whether you want or not, you have to go deep and tell the magic sand exactly what you want, without any abstraction layer in between. This is the time when you want to make use of inline assembly.

This looks something like this:

  asm("cpuid" : "=a"(a), "=b"(b), "=c"(c), "=d"(d) : "a"(0x0));

This returns the manufacturer ID of your CPU to the variables a,b,c and d. All of them have to be either char[8] or size_t.

Calling a function

To call a function in ASM you can simply use the call procedure. According to [1], using call, saves the procedure linking information on the stack and branches to the called procedure specified using the target operand.

One might think now that you could use something like this: asm("call myfunction":::) and call it a day. But not so fast.

You have to do some preparation before using call.

Preparing to use the CALL

Before using call, is to make sure, that the stack is aligned on 16-bit or 32-bit boundaries [2]. Because call stores the 8 byte return address on the stack, the rsp will be unaligned. To counteract this, you want to grow the stack by additional 8 bytes so that things are aligned again.

Since the stack grows downwards (from 0xffffffff to 0x0), rsp has to be decreased by 8.

    asm("sub $8, %%rsp;"::"rsp");

Function Parameters

Usually functions have one or more parameters. To pass them to the called function there are two possible methods: either store them in registers, on on the stack.

Considering that there are only a finite amount of registers on a CPU, the idea of using the stack to store function parameters is not far fetched. In reality the two methods are used both together.

For integers the first nine parameters are stored in rdi, rsi, rdx, rcx, r8, r9 and the rest gets pushed to the stack.

Floating point numbers on the other hand are stored in xmm0 to xmm7 for SSE2 compatible CPUs (most consumer CPUS?).

References

[1] Intel® 64 and IA-32 Architectures Software Developer’s Manual Combined Volumes

[2] Volume 1 of [1]. Chapter 6.2.2 “Stack Alignment”

[3] @cirosantilli x86-assembly-cheat