Probably sometime you will need to write a program in assembly language. For this reason, in this article we will develop a simple and typical executable “Hello World” program in assembly language to familiarize yourself with the process.

In the operating system GNU/Linux there are several ways you can program at low level. The following method is the fastest one and the executable will make direct calls to the Linux kernel (communication with the Linux kernel will happen immediately). Also, the code that we will write for the creation of the program will not link to a library and will not use any ELF interpreter.

Tools needed to assemble and link the program:

a) ‘nasm‘ or ‘gas‘ assembler

b) ‘ld‘ linker

We will use both of these assemblers to show at assembly language level both Intel and AT&T syntax in the “Hello World” example.

The Linux kernel (32-bit) runs in protected mode and mainly uses ELF format for binary and executable files and programs.

Also, each program can be divided into three sections. Section “.text” (read-only) used for program code, section “.data” (read and write) used for data and section “.bss” (read and write) used for data that are not initialized in the code but occur during program execution. Note that section “.text” is mandatory while the rest can be absent.

The program in assembly language with Intel syntax (hello.asm):

section .text

    global _start

_start:

        ; write our string to stdout.

        mov     edx,len   ; third argument: message length.
        mov     ecx,msg   ; second argument: pointer to message to write.
        mov     ebx,1     ; first argument: file handle (stdout).
        mov     eax,4     ; system call number (sys_write).
        int     0x80	  ; call kernel.

        ; and exit.

	mov	ebx,0	  ; first syscall argument: exit code.
        mov     eax,1     ; system call number (sys_exit).
        int     0x80	  ; call kernel.

section .data

msg     db      "Hello, world!",0xa      ; the string to print.
len     equ     $ - msg                  ; length of the string.

The program in assembly language with AT&T syntax (hello.S):

.text

    .global _start

_start:

        # write our string to stdout.

        movl    $len,%edx       # third argument: message length.
        movl    $msg,%ecx       # second argument: pointer to message to write.
        movl    $1,%ebx	        # first argument: file handle (stdout).
        movl    $4,%eax	        # system call number (sys_write).
        int     $0x80           # call kernel.

        # and exit.

        movl    $0,%ebx         # first argument: exit code.
        movl    $1,%eax         # system call number (sys_exit).
        int     $0x80           # call kernel.

.data

msg:
        .ascii  "Hello, world!\n"      # the string to print.
        len = . - msg                  # length of the string.

Creating the object code of the program (hello.o):

efxa@freedom.org.gr:~$ nasm -f elf hello.asm

or

efxa@freedom.org.gr:~$ as -o hello.o hello.S

Generation of executable program code (hello):

efxa@freedom.org.gr:~$ ld -s -o hello hello.o

Immediate execution of the program:

efxa@freedom.org.gr:~$ ./hello