In the following I present a simple assembly example that can be compiled and executed under Linux. 1) We start out with the standard C Hello World program. #include int main(int argc, char **argv) { printf("Hello world\n"); return 0; } 2) You can compile this code with "gcc -S -masm=intel -m32" to get the assembly version that the C compiler would generate (in Intel syntax, 32 bit legacy mode). It looks as follows. .file "test.c" .intel_syntax noprefix .section .rodata .LC0: .string "Hello world" .text .globl main .type main, @function main: .LFB0: .cfi_startproc push ebp .cfi_def_cfa_offset 8 .cfi_offset 5, -8 mov ebp, esp .cfi_def_cfa_register 5 and esp, -16 sub esp, 16 mov DWORD PTR [esp], OFFSET FLAT:.LC0 call puts mov eax, 0 leave .cfi_restore 5 .cfi_def_cfa 4, 4 ret .cfi_endproc .LFE0: .size main, .-main .ident "GCC: (SUSE Linux) 4.6.2" .section .comment.SUSE.OPTs,"MS",@progbits,1 .string "ospwg" .section .note.GNU-stack,"",@progbits 3) The C compiler introduces a lot of additional debug details so I decided to rewrite it to a simpler form and commment every line. Assemble with "gcc -m32" to get the final executable. .intel_syntax noprefix # Specify the usage of INTEL syntax with no prefixes .code32 # Specify that file should be compiled in 32 bit legacy mode .section .rodata # Section containing read only data Hello: .string "Hello world" # Define label Hello for a memory region containing "Hello world" .text # Section contianing text <- code .globl main # Definition of global label: main main: # Label main in the text section push offset Hello # Set the address of label Hello as the first argument on the stack call puts # Call puts (from libc, argument is string pointed to by EDI) pop EAX # Clean the stack by popping the argument from it mov EAX, 0 # Move the return value 0 to EAX ret # Return from main 4) I would recommend the usage of NASM when working with Intel syntax since it uses the traditional approach compared to GCC. It can also be used with a variety of systems. In the following is the assembly ported to NASM syntax. To generate a binary, first assemble with NASM (nasm -f elf -o output). Then generate the binary with GCC (gcc -m32 output). [BITS 32] ; Specify that file should be compiled in 32 bit legacy mode extern puts ; Specify external symbols SECTION .rodata ; Section containing read only data Hello: db 'Hello world', 0 ; Define label Hello for a memory region containing "Hello world" SECTION .text ; Section contianing text <- code global main ; Definition of global label: main main: ; Label main in the text section push Hello ; Set the address of label Hello as the first argument on the stack call puts ; Call puts (from libc, argument is string pointed to by EDI) pop EAX ; Clean the stack by popping the argument from it mov EAX, 0 ; Move the return value 0 to EAX ret ; Return from main 5) Some notes about the assembly presented above:: a) The assembly file always ends with a newline character! b) As you can notice the C compiler changed the call from "printf" into "puts" since it has a simpler interface. c) The string was put into the read only segment of data. If you want writeable data, use the section ".data". d) 32 bit legacy mode allows you to use the same assembly file on both 32 and 64 bit machines without problems with pointer sizes or function interfaces. 6) Have fun!