The first code you ever wrote was probably something like:
public class MyFirstClass {
public static void main(String[] args) {
System.out.println("Hello World!");
}
}
Assembly is a little bit more complicated than Java, so it is necessary to cover some basic concepts before you are ready to write to the terminal. The good news is that we are ready to write to the terminal!
Writing to the terminal works via a system call, just like when we exited with exit code 0. Lets have a look at the code.
.section .data
msg:
.string "Hello world\n"
.section .text
.globl _start
_start:
movq $1, %rax
movq $1, %rdi
movq $msg, %rsi
movq $12, %rdx
syscall
movq $60, %rax
movq $0, %rdi
syscall
We start off with our data section. Our data section is no longer empty. Now, we define a string with the value “Hello world\n”. We give this string the label msg
.
In the text section we define our entry point as before, and we exit with code 0 as before. However we also have the five lines that output our message to the terminal:
movq $1, %rax
movq $1, %rdi
movq $msg, %rsi
movq $12, %rdx
syscall
Before transferring control to the linux kernel we have to move four values into registers. First we have to put 1 in the rax
register and 1 in the rdi
register. Don’t worry, the significance of these two values will be explained later! We put the address of the data we would like to write in the rsi
register. In this case, we can reference the address of the data we would like to write with the label msg
. Finally, in the rdx
register we put the number of bytes we would like to write. This is asci, so each character is one byte, so our string is 12 bytes long, including the newline character.
If you put this code in a film named helloworld.s
and execute
as helloworld.s -o helloworld.o
ld helloworld.o -o helloworld
This will create a binary in the same directory named helloworld. When you run this binary you should see “Hello world” printed to the terminal!