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