Next Previous Contents

6. QUICK START

Finally, if you still want to try this crazy idea and write something in assembly (if you've reached this section -- you're real assembly fan), I'll herein provide what you will need to get started.

As you've read before, you can write for Linux in different ways; I'll show example of using pure system calls. This means that we will not use libc at all, the only thing required for our program to run is kernel. Our code will not be linked to any library, will not use ELF interpreter -- it will communicate directly with kernel.

I will show the same sample program in two assemblers, nasm and gas, thus showing Intel and AT&T syntax.

You may also want to read Introduction to UNIX assembly programming tutorial, it contains sample code for other UNIX-like OSes.

6.1 Tools you need

First of all you need assembler (compiler): nasm or gas. Second, you need linker: ld, assembler produces only object code. Almost all distributions include gas and ld, in binutils package. As for nasm, you may have to download and install binary packages for Linux and docs from the nasm webpage; however, several distributions (Stampede, Debian, SuSe) already include it, check first.

If you are going to dig in, you should also install kernel source. I assume that you are using at least Linux 2.0 and ELF.

6.2 Hello, world!

Linux is 32bit and has flat memory model. A program can be divided into sections. Main sections are .text for your code, .data for your data, .bss for undefined data. Program must have at least .text section.

Now we will write our first program. Here is sample code:

NASM (hello.asm)


section .data                           ;section declaration

msg     db      "Hello, world!",0xa     ;our dear string
len     equ     $ - msg                 ;length of our dear string

section .text                           ;section declaration

                        ;we must export the entry point to the ELF linker or
    global _start       ;loader. They conventionally recognize _start as their
                        ;entry point. Use ld -e foo to override the default.

_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

GAS (hello.S)


.data                                   # section declaration

msg:
        .string "Hello, world!\n"       # our dear string
        len = . - msg                   # length of our dear string

.text                                   # section declaration

                        # we must export the entry point to the ELF linker or
    .global _start      # loader. They conventionally recognize _start as their
                        # entry point. Use ld -e foo to override the default.

_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

6.3 Producing object code

First step of building binary is producing object file from source, by invoking assembler; we must issue the following:

For nasm example:

$ nasm -f elf hello.asm

For gas example:

$ as -o hello.o hello.S

This will produce hello.o object file.

6.4 Producing executable

Second step is producing executable file itself from object file, by invoking linker:

$ ld -s -o hello hello.o

This will finally build hello ELF binary.

Hey, try to run it... Works? That's it. Pretty simple.

If you get interested and want to proceed further, you may want to look through Linux assembly projects, they contain PLENTY of source code and examples.


Next Previous Contents