Tyler St. Onge

Assembly - Hello World

I recently stumbled across a bunch of old Ezines from what I think is the 90s about virus development in assembly. It seemed like a pretty cool topic to look into and I figured it would be an excellent way to expand my knowledge of Assembly and coding in general. So let’s start with a hello world in Assembly. I am writing in 32bit assembly on Linux and I use YASM to assemble the code but NASM itself would work fine as well.


The Code

section .text
	global _start
_start:
	mov	eax, 0x04
	mov	ebx, 1
	mov	ecx, hello
	mov	edx, len
	int	0x80

	mov	eax, 0x01
	int	0x80

section .data
hello	db	"Hello, world!",0x0a
len	equ	$ - hello

Explanation

So at first glance Assembly looks like a load of jibberish, but it is actually pretty easy to understand. Let’s break it down section by section.

section .text
	global _start

All this section is doing is declaring that we are within the .text, which is the section that is going to contian all the code of the program, and that the entry to our program is the _start label.

start:
	mov	eax, 0x04
	mov	ebx, 1
	mov	ecx, hello
	mov	edx, len
	int	0x80

This is the meat of our program. First it defines the following code under _start, programs can divide their code into multiple labels but for a small program like this we can easily just leave it all under this one label. We continue by moving the hex value 0x04, which is what tells the computer we want to use the write command, into the register eax. How did I know that 0x04 was the call for write? It is stored on your computer in ‘/usr/include/asm/unistd.h’ or you can just google linux syscalls. The next command moves the value 1 into ebx. This is how we specify that we want to print to stdout so the text will be displayed in the terminal, we could have alternatively supplied a file descriptor to write to but I’ll talk about that in the next tutorial. After that, we move our string (which we will define in the .data section) into ecx, and we move the length of the string into edx. After we have set all the proper registers we use the interrupt 0x80 to tell the computer we have everything set for the function to run, which then causes the string to be printed.

mov	eax, 0x01
	int	0x80

This is how a program is exited in Assembly. We just move the value 0x01, which is defined as exit in the syscalls, then we int 0x80 to tell the computer we’ve set the proper registers and the function fires exiting the program.

section .data
hello	db	"Hello, world!",0x0a
len	equ	$ - hello

In the first line of this code we are telling opening the new .data section. This is where we define any constant data our program uses. As a side note, any variables declared here cannot be changed when the program is running. The first variable we declare is hello, and we terminate the string with 0x0a, which will make the computer create a new line after the data. The next line sets the variable len equal to the address of the beginning of the line of the current instruction minus the location of hello, this will evaluate to the size of hello.

Outro

Compiling the code is different depending on you system and architecture. I am compiling with YASM and on a Linux x86_64 system, so I need extra flags to compile and link the 32bit code on the 64bit system. This can all be done like this (assuming you named your file hello.asm):

yasm -p nasm -f elf hello.asm
ld -s -o hello hello.o -m elf_i386

Now you can run your hello command and it should print out your string. Next time I will get into how to open, read, write, and close files.

Newer >>