Date created: Sunday, April 7, 2019 8:59:35 PM. Last modified: Monday, June 3, 2019 8:05:38 AM

Assembling, Linking, Loading (as and yasm)

References:
x86-64 Assembly Language Programming with Ubuntu By Ed Jorgensen

"The human readable source file is converted into an object file by the assembler. In the most basic form, the object file is converted into an executable file by the linker. The loader will load the executable file into memory."

 

yasm

$ cat basic.asm
;
; Constants
;

section .data

EXIT_SUCCESS equ 0  ; return/exit code
SYS_exit equ 60     ; syscall code for terminate

bVar1 db 5
bVar2 db 3


;
; Global vars
;

section .bss

bRet db 1


;
; Code
;

section .text
global _start
_start:

mov al, byte [bVar1]
add al, byte [bVar2]
mov byte [bRet], al

mov rax, SYS_exit
mov rdi, EXIT_SUCCESS
syscall

 

Compile the above Intel syntax assembly to an ELF64 format machine code object file and optionally (using -l) create a list file. The list file is purely for debugging and not needed for further compilation, it will contain the opcodes (machine code) for the compiled assembly used in the .o file:

$ yasm -Worphan-labels -g dwarf2 -f elf64 basic.asm -l basic.lst
$ file basic.o
basic.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped

# Optionally dump the machine code from the compiled object file with `objdump`
$ objdump -d -M intel -S basic.o
# Or `cat` the list file generated by `yasm` with -l
$ cat basic.lst 1 %line 1+1 basic.asm 2 3 4 5 6 7 8 9 10 11 [section .data] 12 13 EXIT_SUCCESS equ 0 14 SYS_exit equ 60 15 16 00000000 05 bVar1 db 5 17 00000001 03 bVar2 db 3 18 19 20 21 22 23 24 [section .bss] 25 26 00000000 01 bRet db 1 27 28 29 30 31 32 33 [section .text] 34 [global _start] 35 _start: 36 37 00000000 8A0425[00000000] mov al, byte [bVar1] 38 00000007 020425[00000000] add al, byte [bVar2] 39 0000000E 880425[00000000] mov byte [bRet], al 40 41 00000015 48C7C03C000000 mov rax, SYS_exit 42 0000001C 48C7C700000000 mov rdi, EXIT_SUCCESS 43 00000023 0F05 syscall

 

Link the compiled object file(s) and any system references/libraries into an single executable:

$ ld -g -o basic basic.o

$ file ./basic
basic: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, not stripped

$ ./basic
$ echo $?
0

 

as

By default as expects AT&T syntax assembly code however, with minor modifications it can be used with Intel synatx.

Compile the following Intel syntax assembly into an object file:

$ cat exit_syscall.s

.intel_syntax noprefix
.section .data

.section .text
.globl _start
_start:

mov rax, 60
mov rdi, 0
syscall

$ as exit_syscall.s -o exit_syscall.o

$ file exit_syscall.o
exit_syscall.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped

# Optionally dump the opcodes using `objdump` from the machine code compiled object file:
$ objdump -d -M intel -S exit_syscall.o

exit_syscall.o: file format elf64-x86-64


Disassembly of section .text:

0000000000000000 <_start>:
0: 48 c7 c0 3c 00 00 00 mov rax,0x3c
7: 48 c7 c7 00 00 00 00 mov rdi,0x0
e: 0f 05 syscall

Link with ld into an executable binary:

$ ld -o exit_syscall exit_syscall.o

$ file exit_syscall
exit_syscall: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, not stripped

$ ./exit_syscall
$ echo $?
0