How to make a simple Hello World using conventions in C?

2

Knowing some of the conventions in C and the generalization of code it can provide, I tried to implement my "Hello World":

global main
extern printf

section .data
helloworld db 'Hello World',0

section .text
main:
    push helloworld
    call printf
    ret

Soon followed by nasm -fwin64 test.asm e gcc test.obj . The compilation is perfect. Since I do not know much about Assembly (just a few languages at the highest level), I do not see what's wrong. What happens to my program? Why does this happen? How do I fix this?

PS: Machine running Windows 8, Intel i3 64-bit CPU and linker MinGW64. By simple, I mean "no WinAPI conventions."

    
asked by anonymous 08.01.2015 / 02:35

1 answer

4

Every function must have its own stack frame, this is part of the function convention. So since main is a function, you should start the stack frame with push ebp and mov ebp, esp and end with leave . The reason you have to do this with main is because it not is the main function of your executable. In fact there will be another, provided by the compiler, which will call main . In Windows it would be WinMain whereas in Linux it would be _start . So the code needs to look like this:

global main
extern printf

section .data
helloworld db 'Hello World',0 

section .text
main:
    push    ebp
    mov     ebp, esp
    push    helloworld
    call    printf
    leave              ; Equivalente a "pop ebp"
    mov     eax, 0     ; Retorne 0
    ret

But you are also interested in using x64 code. It will not work that way. The convention for passing arguments in x86 numerics (or pointers as is the case) is to add them in the stack. But in the case of x64 the convention changes to use the following registers for the first 6 parameters: rdi , rsi , rdx , rcx , r8 and r9 . From the seventh onwards, you'll need to stack as usual. So the code looks like this:

global main
extern printf

section .data
helloworld db 'Hello World',0 

section .text
main:
    push    rbp
    mov     rbp, rsp
    mov     rdi, helloworld
    call    printf
    leave
    mov     rax, 0     ; Retorne 0
    ret

Note, however, that different systems or different architectures may change these conventions. You will always need to choose exactly what your target system is and search its conventions.

    
08.01.2015 / 17:40