If you are just using GCC as a linker and don't care about the C runtime then you can exclude it (as Jester pointed out) by passing -nostdlib to gcc . You then need to provide a _start symbol so the code would look like:
SECTION .DATA
hello: db 'Hello world!',10
helloLen: equ $-hello
SECTION .TEXT
GLOBAL _start
_start:
; Write 'Hello world!' to the screen
mov eax,4 ; 'write' system call
mov ebx,1 ; file descriptor 1 = screen
mov ecx,hello ; string to write
mov edx,helloLen ; length of string to write
int 80h ; call the kernel
; Terminate program
mov eax,1 ; 'exit' system call
mov ebx,0 ; exit with error code 0
int 80h ; call the kernel
You'd assemble and link it like this:
nasm -f elf file.asm
gcc -m32 -nostdlib -o file file.o
Alternatively you can link directly with ld so you could also do this:
nasm -f elf file.asm
ld -melf_i386 -o file file.o
This would generate a 32-bit Linux executable called file
Using C Library/runtime
Although I don't think the following is what you intended, someone may find the following information useful:
You can use GCC and have the C library available to your assembly code by renaming _START to main. The C runtime contains an entry point called _start that handles initialization and then calls a function called main. You can take advantage of the C library but main has to setup the stack frame correctly and properly clean it up and return when finished since main will be treated as a C function. The code would look something like this:
EXTERN printf ; Tell the assembler printf is provided outside our file
SECTION .DATA
hello: db 'Hello world!',10,0 ; Null terminate for printf
helloLen: equ $-hello-1 ; Exclude null by reducing len by 1
SECTION .TEXT
GLOBAL main
; main is now a C function
main:
push ebp ; Setup stack frame
mov ebp, esp
push ebx ; We need to preserve EBX (C Calling convention)
; Write 'Hello world!' to the screen
mov eax,4 ; 'write' system call
mov ebx,1 ; file descriptor 1 = screen
mov ecx,hello ; string to write
mov edx,helloLen ; length of string to write
int 80h ; call the kernel
; Write 'Hello World!' with C printf
push hello ; push the address of string to print
call printf ; call printf in C library
add esp, 4 ; Restore stack pointer
; push hello pushed 4 bytes on stack
mov eax, 0x0 ; Return value of 0
pop ebx ; Restore EBX
leave
ret ; Return to C runtime which will cleanup and exit
This example uses both int 0x80 system call to write standard output, and uses C printf to do the same. You can assemble and link to an executable called file with:
nasm -f elf file.asm
gcc -m32 -o file file.o
gcc -nostdlibalso make sure you call your entry point_startin lower case. - Jester