Hello EZ.
Here is something I only found out after a few hours of research. Calling C functions on 32 bit systems is pretty easy. You just push your parameters on the stack. Here is a simple hello world example that uses the printf function of C. It is NASM code for Linux. The keyword extern tells the compiler that printf is defined somewhere else. Using gcc will provide the C libraries.
;type this to create an executable file:
;
;nasm -f elf hello.asm
;gcc -o hello hello.o
;
;this code only works on 32 bit Linux
;
extern printf
section .data
message: db "Hello World", 10, 0
section .text
global main
main:
push message
call printf
mov eax, 1 ;exit syscall
mov ebx, 0
int 80h
Since I use a book that only covers 32 bit assembly, I got into trouble trying it on my 64 bit system. The code above threw a segmentation fault. I found the answer in this document:
www.x86-64.org/documentation/abi.pdfObviously calling C functions became more complicated. First you need to know the classification of your parameter (MEMORY, INTEGER, SSE, ...). For INTEGER arguments general purpose registers are used to pass the parameters. The order is the following:
%rdi, %rsi, %rdx, %rcx, %r8 and %r9
That means %rdi is used for the first parameter, %rsi for the second and so on. The printf parameters in our example are INTEGER, because you pass memory addresses instead of the string itself. The printf function however has another speciality. The number of arguments is arbitrary. The ellipsis in the declaration shows this:
int printf ( const char * format, ... );
Because of that you also have to put the number of arguments you passed in vector registers into %al. Vector registers are %xmm0 - %xmm15 and %ymm0-%ymm15 The following example shows the implementation of a hello world using printf with two parameters. Since no vector registers are used, 0 is put into %al.
;type this to create an executable file:
;
;nasm -f elf64 -g -F stabs hello.asm
;gcc -o hello hello.o
;
;this code only works on 64 bit Linux
;
extern printf
section .data
message: db "Hello World", 0
type: db "%s",10,0
section .text
global main
main:
mov rdi, type ;first parameter
mov rsi, message ;second parameter
mov rax, 0 ;no floating point register used
call printf
mov rax, 1 ;exit syscall
mov rbx, 0
int 80h
This code works well. The call to the printf function is equal to this (yes, I could have done this with one argument, but I want to show how to use several of them):
printf("%s\n", "Hello World");
This example should be enough for a quick start into using C functions in 64 bit assembly. Have a look at the documentation I linked above to get all the information you need.
Deque