GNU/Linux Programmer's Solver - ASM

Hello World program in ASM. Basic structure, comments and string literals
PROGRAMMING ASM X86_64 HELLO WORLD
    .global _start
    .extern puts
    .extern exit
    .text
    # This is a comment
_start:
    mov  $msg, %rdi     # THis is a comment in a code line
    call puts
    call exit

.section .rodata
msg: .asciz "Hello World GAS and C!!"

Assembly language is the lowest level language we can use without writing machine code (zeros and ones) directly. It’s not really a language but a family of languages, which are different for each type of platform/processor. In this book, we will use the x86_64 platform, as it is the most widespread, at least for now. Whenever possible, we will show you two versions of the programs.

The first using the standard C library and the second using system calls, although in the second case we will have to limit the functionality of the programs a bit so that they don’t become endless.

The entry point for assembly programs in GNU/Linux is _start. The two functions we use belong to the standard C library. puts displays a character string in the console and exit terminates the program.

I’M A NEWBY

Most languages, compiled or interpreted, automatically include code to terminate programs, however, in assembly we have to do everything ourselves. The exit function makes a system call to the operating system to tell it that the process must terminate. Otherwise, the program would continue executing with whatever the contents of memory are next, which usually ends with a segmentation fault.

Each operating system defines its own ABI, a series of rules and formats for the execution of binary code among other things. GNU/Linux uses the System V ABI. As far as we, as programmers, are concerned, the part of the ABI that interests us is the one that indicates how we should call functions and the operating system. For the System V ABI and x86_64 platform, this is the relevant information:

  • RDI, RSI, RDX, RCX, R8 and R9 are used to pass parameters to functions or system calls
  • RAX is used as a return value. In the case of system calls, it is also used to indicate the number of the syscall we want to execute.

As you can see, the program loads the pointer to the string we want to print into RDI and then calls the function.

NOW YOU KNOW WHY

You may have heard that it’s not a good practice to define functions with many parameters. As you can see, when we reach the assembly level, the more parameters there are, the more work we have to do. But what’s even worse is that when we run out of registers, the values will be stored on the stack, which is much slower to access, adding an extra penalty to the execution time of our functions.

In general, assembly language does very few things for us. However, as a trade-off, it allows us to do practically whatever we want.

To compile this program using the standard GNU toolchain, we must use the following commands:

$ as -o hello1.o hello1.s
$ ld -I/usr/bin/ld.so -lc -o hello1-asm hello1.o

The first command invokes the assembler to compile our code, which we usually store in a file with a .s extension. Once assembled, we must link it to produce an executable and, in this case, also link the standard C library to be able to use the puts and exit functions.

I’M A NEWBIE

Toolchain is the generic name given to the set of tools that are needed to produce programs for a specific platform. It usually consists of the following programs:

addr2line  Converts memory addresses to line numbers
            in source code (ADDRess to Line)
ar         File archiver. Used to generate
            static libraries (ARquiver)
as         Assembler (Assembler)
c++filt    Decodes C++ symbol names
cpp        C pre-processor (C Pre-Processor)
elfedit    Allows modifying header and properties of ELF programs
gcc        The C compiler (GNU C Compiler)
gcov       Tool for coverage testing
            (GNU Coverage tool)
gcov-dump  Tool for displaying information about program coverage
gprof      Tool for performance analysis (GNU Profiler)
ld         The linker
lto-dump   Used to display LTO files
            (Link-Time Optimisations)
nm         Lists symbols in objects
objcopy    Object file manipulation
objdump    Displays information about object files
ranlib     Generates indexes for files (static libraries)
            to speed up compilation
readelf    Displays information about ELF files
strings    Displays character strings in binary files
size       Size of the file by memory sections
strip      Removes unnecessary parts from executable files

The assembler version using system calls will be shown with assembler in Intel format and using nasm as the assembler. The program would be the following:

    global _start
    
_start:
    ;;  Comments start with ;
    mov rax, 1      ; In line comment
    mov rdi, 1
    mov rsi, msg
    mov rdx, size
    syscall

    ;; Exit program
    mov rax, 0x3c ; SYS_exit = 0x3c
    mov rdi, 0

    syscall

msg:
    db 'Hello World from NASM!',0x0a    
size:   equ $ - msg

To implement the program with system calls, we must use two of these calls. The SYS_write call, which allows us to display messages on the screen if we write to standard output (file descriptor number 1), and the SYS_exit system call, to terminate the program cleanly.

As you can see, the ABI is the same as for function calls, with the exception that the RAX register must be loaded with the value of the system call we want to execute.

To compile this program with nasm, we can use the following commands:

$ nasm -f elf64 -o hello2.o hello2.asm
$ ld -o hello2-asm hello2.o

The main difference is that now we don’t need LibC and our program is much smaller and doesn’t depend on any external library.

Unlike other languages, we can’t offer you a name and creation date. Assembly language was born with the first processor, and a new version emerges whenever a new processor is developed or improved.

Summary

  • Compiled Language
  • Extension: asm/s
  • Line Terminator : Carriage Return
  • Group Instructions with : Does not exist
  • Multiline Comments : Do not exist
  • Comments same line: ; or @ or #
  • String Delimiter: "string"
  • No way to write text directly
  • Multiline string support: Not supported.
  • Does not Support HERE-DOCS
  • Entry Point: _start

Related Posts

GNU/Linux Programmer's Solver - Introduction

Programming exercises in 18 Programming Languages

Read

linuxprogramming

GNU/Linux Programmer's Solver
Chapter 1 - Hello World

Hello World is the first program you write when learning a new language and there are good reasons for that

Read

PROGRAMMING HELLO WORLD

Return to Home Page