Skip to content

Latest commit

 

History

History
2959 lines (2767 loc) · 50.5 KB

assembly.md

File metadata and controls

2959 lines (2767 loc) · 50.5 KB

x64 Assembly

Resources

Compiling with NASM

Compile an x64 assembly program?
section .data
    message db "sample assembly program", 10, 0
    length equ $ - message

section .bss
section .text
    global main

main:
    push rbp
    mov rbp, rsp

    mov rax, 1
    mov rdi, 1
    mov rsi, message
    mov rdx, length
    syscall

    mov rsp, rbp
    pop rbp

    mov rax, 60
    mov rdi, 0
    syscall
sample: sample.o
    gcc -Wall -g3 -Og -no-pie sample.o -o sample
sample.o: sample.asm
    nasm -f elf64 -g -F dwarf sample.asm -l sample.lst

Resources

  • Beginning x64 Assembly Programming - Chapter 3

References


Debugging with GNU Debugger

Debug a compiled program with gdb?
gdb --quiet executable

Resources

  • Beginning x64 Assembly Programming - Chapter 3

References


List source lines in debugging?
list
list 10
`help list` or `h l`

Resources

  • Beginning x64 Assembly Programming - Chapter 3

References

Change the line number of source listing?

Description

show listsize
set listsize 20

Resources

  • Beginning x64 Assembly Programming - Chapter 3

References

Set disassembly flavor in gdb?
show disassembly-flavor
set disassembly-flavor intel
set disassembly-flavor att
help set disassembly-flavor

Resources

  • Beginning x64 Assembly Programming - Chapter 3

References

Store gdb configurations in file for future use?
echo 'set disassembly-flavor intel' >> $HOME/.gdbinit

Resources

  • Beginning x64 Assembly Programming - Chapter 3

References

Disassemble a function or line of source in gdb?
disassemble main
disassemble 'path/to/source.cpp'::func
help disassemble

Resources

  • Beginning x64 Assembly Programming - Chapter 3

References

Examine an address in memory in gdb?
x/s 0x654321
x/s &message
x/d 0x654321
x/x $rip
help x

Resources

  • Beginning x64 Assembly Programming - Chapter 3

References

Set breakpoints in gdb?

Description

break main
help break

Resources

  • Beginning x64 Assembly Programming - Chapter 3

References

Start execution of the debugging program in gdb?
run
help run

Resources

  • Beginning x64 Assembly Programming - Chapter 3

References

Inspect registers in gdb?

Description

info registers
info all-registers
help info registers
help info all-registers

Resources

  • Beginning x64 Assembly Programming - Chapter 3

References

Inspect the breakpoint, stack, threads and other resources of the debugging program in gdb?
info breakpoints
info stack
info threads
info source
help info breakpoints
help info stack
help info threads
help info source

Resources

  • Beginning x64 Assembly Programming - Chapter 3

References

Manipulate breakpoints in gdb?

Description

disable breakpoint 1
enable breakpoint 1
delete breakpoint 1
help disable breakpoint
help enable breakpoint
help delete breakpoint

Resources

  • Beginning x64 Assembly Programming - Chapter 3

References

Change executation of the debugging program in gdb?
continue
next
step
help continue
help next
help step
help finish

Resources

  • Beginning x64 Assembly Programming - Chapter 3

References

Print variables through debugging session?

Description

print
help print

Resources

  • Beginning x64 Assembly Programming - Chapter 3

References

Enable TUI in gdb:
tui enable
help tui

Resources

  • Beginning x64 Assembly Programming - Chapter 3

References

Analyzing Binary Objects

Read the ELF header of an executable object?

Description

readelf --file-header ./program

Resources

  • Beginning x64 Assembly Programming - Chapter 8

References

Read symbols of an executable object?

Description

readelf --symbols ./program | grep -E 'main|start|Num:.*' --color

Resources

  • Beginning x64 Assembly Programming - Chapter 8

References

Sort executable object symbols based on its memory locations?
readelf --symbols ./program | sort -k 2 -r

Resources

  • Beginning x64 Assembly Programming - Chapter 8

References

Numeric Representations

Convert decimal, binary, and hexadecimal representations of integral and floating point numbers?

Resources

  • Beginning x64 Assembly Programming - Chapter 2

References


Indicate that a literal number is in octal base in x64 assembly?

By appending q to the number.

section .data
    O_CREATE equ 00000100q

Resources

  • Beginning x64 Assembly Programming - Chapter 20

References

Indicate that a literal number is in hexadecimal base in x64 assembly?

By appending an h at the end of a number:

2000000h

Resources

  • Beginning x64 Assembly Programming - Chapter 25

References

Registers

Name x64 registers?
  • rax
  • rbx
  • rcx
  • rdx
  • rsi
  • rdi
  • rbp
  • rsp
  • r8
  • r9
  • r10
  • r11
  • r12
  • r13
  • r14
  • r15

Resources

  • Beginning x64 Assembly Programming - Chapter 2

References

What is the name of Instruction Pointer register?

rip


Resources

  • Beginning x64 Assembly Programming - Chapter 2

References

Name the flag registers?

Description

Name Symbol Bit Content
Carry CF 0 Previous instruction had a carry
Parityp F 2 Last byte has even number of 1s
Adjust AF 4 BCD operations
Zero ZF 6 Previous instruction resulted a zero
Sign SF 8 Previous instruction resulted in most significant bit equal to 1
Direction DF 10 Direction of string operations (increment or decrement)
Overflow OF 11 Previous instruction resulted in overflow

Resources

  • Beginning x64 Assembly Programming - Chapter 2

References

Name SIMD registers?

Description

xmm ymm zmm


Resources

  • Beginning x64 Assembly Programming - Chapter 2

References

Invoking System Calls

What header contains Linux system calls?

/usr/include/asm/unistd_64.h


Resources

  • Beginning x64 Assembly Programming - Chapter 20

References

Write exit procedure in x64 Assembly?

Description

section .data
section .bss
section .text
    global main

main:
    mov rax, 60
    mov rdi, 0
    syscall

Resources

  • Beginning x64 Assembly Programming - Chapter 1

References

Exit program without directly writing the exit syscall?

Description

section .text
    global main

main:
    ret

Resources

  • Beginning x64 Assembly Programming - Chapter 4

References

Memory Sections

Create values in data section of memory?
section .data
    message db "sample program", 10, 0
    message_length equ $ - message - 1
    pi dq 3.14

section .text
    global main

main:
    push rbp
    mov rbp, rsp

    ; write
    mov rax, 1
    mov rdi, 1
    mov rsi, message
    mov rdx, message_length
    syscall

    mov rsp, rbp
    pop rbp

    ; exit
    mov rax, 60
    mov rdi, 0
    syscall

Resources

  • Beginning x64 Assembly Programming - Chapter 4

References

Consecutively store a sequence of data into read-only memory section?
section .data
    word_array times 5 dw 0 ; array of 5 words containing 0

Resources

  • Beginning x64 Assembly Programming - Chapter 8

References

Preserve uninitialized variables in a writable memory section?

Description

section .bss
    bvar resb 10
    wvar resw 5
    dvar resd 1
    qvar resq 100

Resources

  • Beginning x64 Assembly Programming - Chapter 8

References

External Functions

Use external functions from C in x64 assembly code?

Description

extern printf

section .data
    string_fmtstr db "%s", 10, 0
    string db "sample program", 0

    integer_fmtstr db "%d", 10, 0
    number dd 37

    float_fmtstr db "%2.6f", 10, 0
    pi dq 3.141592

section .text
    global main

main:
    push rbp
    mov rbp, rsp

    ; printf
    mov rax, 0 ; do not use xmm registers
    mov rdi, string_fmtstr
    mov rsi, string
    call printf

    ; printf
    mov rax, 0 ; do not use xmm registers
    mov rdi, integer_fmtstr
    mov rsi, [number]
    call printf

    ; printf
    mov rax, 1 ; use xmm registers
    movq xmm0, [pi]
    mov rdi, float_fmtstr
    call printf

    ; exit
    mov rax, 60
    mov rdi, 0
    syscall

Resources

  • Beginning x64 Assembly Programming - Chapter 4

References

Integral Arithmetic Operations

Add and subtract two integral integers?

Description

section .data
    number1 dq 36
    number2 dq 3

section .bss
    result resq 1

section .text
    global main

main:
    push rbp
    mov rbp, rsp

    ; addition
    mov rax, [number1]
    add rax, [number2]
    mov [result], rax ; 39

    ; subtration
    mov rax, [number1]
    sub rax, [number2]
    mov [result], rax ; 33

    mov rsp, rbp
    pop rbp

    xor rax, rax
    ret

Resources

  • Beginning x64 Assembly Programming - Chapter 9

References

Increment and decrement a value stored on a writable variable?
section .data
    number1 dq 36
    number2 dq 3

section .bss
    result resq 1
    modulo resq 1

section .text
    global main

main:
    push rbp
    mov rbp, rsp

    ; increment
    mov rax, [number1]
    inc rax
    mov [result], rax

    ; decrement
    mov rax, [number1]
    dec rax
    mov [result], rax

    mov rsp, rbp
    pop rbp

    xor rax, rax
    ret

Resources

  • Beginning x64 Assembly Programming - Chapter 9

References

Shift arithmetic values stored in writable variables?
section .data
    number1 dq 36
    number2 dq 3

section .bss
    result resq 1
    modulo resq 1

section .text
    global main

main:
    push rbp
    mov rbp, rsp

    ; shift arithmetic left
    mov rax, [number1]
    sal rax, 2 ; multiply by 4
    mov [result], rax

    ; shift arithmetic right
    mov rax, [number1]
    sar rax, 2 ; divide by 4
    mov [result], rax

    mov rsp, rbp
    pop rbp

    xor rax, rax
    ret

Resources

  • Beginning x64 Assembly Programming - Chapter 9

References

Multiply and divide two integral integers?

Description

  • mul multiplies unsigned integers
  • imul multiplies signed integers
  • imul will store the lower 64 bits of the resulting product in rax and the upper 64 bits in rdx.
  • idiv will divide the dividen in rdx:rax by the divisor in the source operand and store the integer result in rax.
section .data
    number1 dq 36
    number2 dq 3

section .bss
    result resq 1
    modulo resq 1

section .text
    global main

main:
    push rbp
    mov rbp, rsp

    ; multiply
    mov rax, [number2]
    imul qword[number2] ; multiplly rax with number2
    mov [result], rax

    ; divide
    mov rax, [number1]
    mov rdx, 0 ; division uses rdx:rax convention
    idiv qword[number2]
    mov [result], rax
    mov [modulo], rdx

    mov rsp, rbp
    pop rbp

    xor rax, rax
    ret

Resources

  • Beginning x64 Assembly Programming - Chapter 9

References

Floating Point Arithmetic Operations

Specify how many bits each floating point number occupies for exponent and fraction?

A single-precision number is 32 bits, 1 sign bit, 8 exponent bits, and 23 fraction bits.

S   EEEEEEEE        FFFFFFFFFFFFFFFFFFFFFFF
0   1      8        9                     31

A double-precision number is 64 bits, 1 sign bit, 11 exponent bits, and 52 fraction bits.

S   EEEEEEEEEEE     FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
0   1         11    12                                                 63

Resources

  • Beginning x64 Assembly Programming - Chapter 11

References

Add and subtract two floating point numbers?
  • Single precision floating point arithmetic instructions are postfixed with ss
  • Double precision floating point arithmetic instructions are postfixed with sd
section .text
    global main

main:
    push rbp
    mov rbp, rsp

    ; sum floating-point numbers
    movsd xmm0, [number1]
    addsd xmm0, [number2]

    ; difference
    movsd xmm0, [number1]
    subsd xmm0, [number2]

    mov rsp, rbp
    pop rbp

    xor rax, rax
    ret

Resources

  • Beginning x64 Assembly Programming - Chapter 11

References

Multiply and divide two floating point numbers?

Description

  • Single precision floating point arithmetic instructions are postfixed with ss
  • Double precision floating point arithmetic instructions are postfixed with sd
section .text
    global main

main:
    push rbp
    mov rbp, rsp

    ; multiplication
    movsd xmm0, [number1]
    mulsd xmm0, [number2]

    ; division
    movsd xmm0, [number1]
    divsd xmm0, [number2]

    mov rsp, rbp
    pop rbp

    xor rax, rax
    ret

Resources

  • Beginning x64 Assembly Programming - Chapter 11

References

Calculate the square root of a floating point number?
  • Single precision floating point arithmetic instructions are postfixed with ss
  • Double precision floating point arithmetic instructions are postfixed with sd
section .text
    global main

main:
    push rbp
    mov rbp, rsp

    ; square root
    sqrtsd xmm0, [number1]

    mov rsp, rbp
    pop rbp

    xor rax, rax
    ret

Resources

  • Beginning x64 Assembly Programming - Chapter 11

References

Bitwise Operations

Evaluate bit-wise operations?
  • shl and sal shift left but sal has sign extension.
  • shr and sar shift right but sar has sign extension.
section .data
    number1 db 6        ; 00000110
    number2 db 10       ; 00001010

section .text
    global main

main:
    push rbp
    mov rbp, rsp

    mov rax, number1
    xor rax, number2    ; 00001100

    mov rax, number1
    or  rax, number2    ; 00001110

    mov rax, number1
    and rax, number2    ; 00000010

    mov rax, number1
    not rax             ; 11111001

    mov rax, number1
    shl rax, 5          ; 11000000

    mov rax, number1
    shr rax, 3          ; 00000001

    mov rax, number1
    sal rax, 2          ; 00001100

    mov rax, number1
    sar rax, 2          ; 00000011

    mov rax, number1
    rol rax, 3          ; 00011000

    mov rax, number1
    ror rax, 3          ; 10000001

    mov rsp, rbp
    pop rbp
    ret

Resources

  • Beginning x64 Assembly Programming - Chapter 16

References

Set and reset specific bits of numeric variable?
section .data
   variable dq 0

section .text
    global main

main:
    push rbp
    mov rbp, rsp

    ; set bit 4
    bts qword [variable], 4

    ; set bit 7
    bts qword [variable], 7

    ; set bit 8
    bts qword [variable], 8

    ; reset bit 7
    btr qword [variable], 7

    xor rax, rax
    leave
    ret

Resources

  • Beginning x64 Assembly Programming - Chapter 17

References

Check if its 8th bit of a quadword variable is set?
section .data
    variable dq 0

section .text
    global main

main:
    push rbp
    mov rbp, rsp

    ; reset higher memory to use lower memory for comparison
    xor rdi, rdi
    mov rax, 8

    ; check if 8th bit is set by checking carry flag
    ; 1 if bit is set and 0 otherwise
    bt [variable], rax
    setc dil

    xor rax, rax
    leave
    ret

Resources

  • Beginning x64 Assembly Programming - Chapter 17

References

Execution Flow Control

Conditionally change the execution flow?

Description

  • je: jump if equal
  • jne: jump if not equal
  • jg: jump if greater
  • jge: jump if greater or equal
  • jl: jump if lower
  • jle: jump if lower or equal
  • ja: jump if above
  • jae: jump if above or equal
  • jb: jump if below
  • jbe: jump if below or equal
extern printf

section .data
    numerator dq 5
    denominator dq 6
    greater_str db "greater", 10, 0
    less_str db "less", 10, 0

section .text
    global main

main:
    push rbp
    mov rbp, rsp

    mov rax, [numerator]
    mov rbx, [denominator]
    cmp rax, rbx
    jge greater

    mov rax, 0
    mov rdi, greater_str
    call printf
    jmp exit

greater:
    mov rax, 0
    mov rdi, less_str
    call printf

exit:
    xor rax, rax
    mov rsp, rbp
    pop rbp
    ret
break main
run
next
info rflags

Resources

  • Beginning x64 Assembly Programming - Chapter 7

References

Repeating Execution

Repeat execution of a code section by manually counting down?
extern printf

section .data
    counter dq 3
    fmt db "%d", 10, 0

section .text
    global main

main:
    ; make stack frame
    push rbp
    mov rbp, rsp

    ; store initial value
    mov rcx, [counter]

    ; print initial value
    mov rax, 0
    mov rdi, fmt
    mov rsi, rcx
    call printf

repeat:
    ; repeat decrementing until value reached zero
    dec rcx
    cmp rcx, 0
    jne repeat

    ; print result
    mov rax, 0
    mov rdi, fmt
    mov rsi, rcx
    call printf

    ; remove stack frame
    mov rsp, rbp
    pop rbp

    ; return zero value
    xor rax, rax
    ret

Resources

  • Beginning x64 Assembly Programming - Chapter 7

References

Repeat execution of a code section by automatically counting down?

Description

extern printf

section .data
    fmt db "%i", 10, 0
    initial dq 3

section .text
    global main

main:
    ; make stack frame
    push rbp
    mov rbp, rsp

    ; assign initial value
    mov rcx, [initial]

    ; print initial value
    xor rax, rax
    mov rdi, fmt
    mov rsi, rcx
    call printf

    ; printf modified rcx
    mov rcx, [initial]

repeat:
    ; decrement rcx until reached zero
    loop repeat

    ; print result
    xor rax, rax
    mov rdi, fmt
    mov rsi, rcx
    call printf

    ; remove stack frame
    mov rsp, rbp
    pop rbp

    ; return value
    xor rax, rax
    xor rdi, rdi
    ret

Resources

  • Beginning x64 Assembly Programming - Chapter 7

References

Memory Operations

Load the address of an array into a register to run operations on?
section .data
    text db "abc", 0

section .text
    global main

main:
    push rbp
    mov rbp, rsp

    ; load address of first character
    lea al, [text]

    ; point of second character
    inc rax

    ; load address of third character
    lea al, [text + 2]

    mov rsp, rbp
    pop rbp

    xor rax, rax
    ret

Resources

  • Beginning x64 Assembly Programming - Chapter 8

References

Stack Operations

Temporarily store values on memory within the scope of a function?

Description

section .data
    text db "Brian Salehi", 10, 0
    length equ $ - text - 1

section .text
    global main

main:
    push rbp
    mov rbp, rsp

    ; print initial sequence
    mov rax, 1
    mov rdi, 1
    mov rsi, text
    mov rdx, length
    syscall

    ; prepare for reverse operation
    xor rax, rax
    mov rbx, text
    mov rcx, length
    xor r12, r12 ; to store index

store_loop:
    ; push sequence to stack
    mov al, byte [rbx+r12]
    push rax
    inc r12
    loop store_loop

    xor rax, rax
    mov rbx, text
    mov rcx, length
    xor r12, r12

reverse_loop:
    ; pop sequence from stack
    pop rax
    mov byte [rbx+r12], al
    inc r12
    loop reverse_loop
    mov byte [rbx+r12], 0

    ; print reversed string
    mov rax, 1
    mov rdi, 1
    mov rsi, text
    mov rdx, length
    syscall

    mov rsp, rbp
    pop rbp

    xor rax, rax
    ret

Resources

  • Beginning x64 Assembly Programming - Chapter 10

References

Stack Alignment

Write a stack frame for a function?

Description

section .text
    global main

main:
    push rbp
    mov rbp, rsp

    mov rsp, rbp
    pop rbp

    ret

Resources

  • Beginning x64 Assembly Programming - Chapter 12

References

Align the stack with stack frame after function call?

Each function call results in 8 bytes return address being pushed on the stack. It is necessary to make sure to restore the stack to the appropriate value before we leave a function.

section .text
    global main

main:
    push rbp
    call func1
    pop rbp
    ret

func1:
    push rbp
    call func2
    pop rbp
    ret

func2:
    push rbp
    call func3
    pop rbp
    ret

func3:
    push rbp
    pop rbp
    ret

Resources

  • Beginning x64 Assembly Programming - Chapter 13

References

Procedures

Abbreviate function epilogue?
section .text
    global main

main:
    push rbp
    mov rbp, rsp

    leave
    ret

Resources

  • Beginning x64 Assembly Programming - Chapter 12

References

Use calling convention to return error code from a function?

Use xmm0 register for floating-point values and rax register for other values.

section .data
    val dq 0

section .text
    global main

main:
    push rbp
    mov rbp, rsp

    call fail_func
    xor rax, rax

    call success_func
    xor rax, rax

    leave
    ret

fail_func:
    push rbp
    mov rbp, rsp

    mov rax, 1

    leave
    ret

success_func:
    push rbp
    mov rbp, rsp

    mov rax, 0

    leave
    ret

Resources

  • Beginning x64 Assembly Programming - Chapter 12

References

Use calling conventions to transfer variables from callee to caller functions?

Description

  • Following calling conventions are for System V AMD64 ABI:
  • For integral types, registers are rdi, rsi, rdx, rcx, r8, r9 respectively, and additional arguments are passed via the stack and in reverse order so that we can pop off in the right order.
  • Function's return address rip is pushed on the stack, just after the arguments.
  • In function, then rbp is pushed, there maybe another 8 bytes needed to be pushed to align the stack in 16 bytes.
  • For floating point types, registers are xmm0 to xmm7, additional arguments are passed via the stack but not with push instruction. Will be discussed later.
section .text
    global main

main:
    section .data
        .first   dq 1
        .second  dq 2
        .third   dq 3
        .forth   dq 4
        .fifth   dq 5
        .sixth   dq 6
        .seventh dq 7
        .eighth  dq 8
        .ninth   dq 9
        .tenth   dq 10

    section .text
        push rbp
        mov rbp, rsp

        mov rdi, .first
        mov rsi, .second
        mov rdx, .third
        mov rcx, .forth
        mov r8, .fifth
        mov r9, .sixth
        push .tenth
        push .ninth
        push .eighth
        push .seventh
        call func

sum:
    section .text
                        ; first value on stack
                        ; 8 bytes rip pushed onto stack
        push rbp        ; 8 bytes rbp pushed onto stack
        mov rbp, rsp

        xor rax, rax

        add rax, rdi
        add rax, rsi
        add rax, rdx
        add rax, rcx
        add rax, r8
        add rax, r9

        push rbx        ; preserve callee register
        xor rbx, rbx

        mov rbx, qword[rbp+16]  ; first value on stack: + rip + rbp
        add rax, rbx    ; seventh

        mov rbx, qword[rbp+24]
        add rax, rbx    ; eighth

        mov rbx, qword[rbp+32]
        add rax, rbx    ; ningth

        mov rbx, qword[rbp+40]
        add rax, rbx    ; tenth

        pop rbx         ; restore callee register

        mov rsp, rbp
        pop rbp
        ret

Resources

  • Beginning x64 Assembly Programming - Chapter 15

References

Local Memory Sections

Declare function local variables?

Description

extern printf

section .data
    radius dq 10.0

section .text
    global main

main:
    push rbp
    mov rbp, rsp

    call area
    call print

    xor rax, rax
    leave
    ret

area:
section .data
    .pi dq 3.141592     ; local to area

section .text
    push rbp
    mov rbp, rsp

    movsd xmm0, [.pi]
    mulsd xmm0, [radius]
    mulsd xmm0, [radius]

    leave
    ret

print:
section .data
    .fmt db "%f", 10, 0

section .text
    push rbp
    mov rbp, rsp

    mov rax, 1
    mov rdi, .fmt
    call printf

    leave
    ret

Resources

  • Beginning x64 Assembly Programming - Chapter 12

References

External Linkage

Expose a function to external linkage?

arithmetic.asm

section .text
    global sum
    global difference
    global area

sum:
    push rbp
    mov rbp, rsp

    mov rax, rdi
    add rax, rsi

    mov rsp, rbp
    pop rbp
    ret

difference:
    push rbp
    mov rbp, rsp

    mov rax, rdi
    sub rax, rsi

    mov rsp, rbp
    pop rbp
    ret

area:
    section .data
        .pi dq 3.141592

    section .text
        push rbp
        mov rbp, rsp

        movsd xmm1, qword[.pi]
        mulsd xmm0, xmm0
        mulsd xmm0, xmm1

        mov rsp, rbp
        pop rbp
        ret

main.asm

extern sum
extern difference
extern area

section .data
    format_integral db "%i", 10, 0
    format_floating db "%f", 10, 0

section .text
    global main

main:
    push rbp
    mov rbp, rsp

    ; use and print the results of sum function
    mov rdi, 1
    mov rsi, 3
    call sum

    mov rdi, format_integral
    mov rsi, rax
    xor rax, rax
    call printf

    ; use and print the results of difference function
    mov rdi, 7
    mov rsi, 5
    call difference

    mov rdi, format_integral
    mov rsi, rax
    xor rax, rax
    call printf

    ; use and print the results of area function
    mov xmm0, qword[radius]
    call area

    mov rdi, format_floating
    mov rax, 1
    call printf

    mov rsp, rbp
    pop rbp
    ret

Resources

  • Beginning x64 Assembly Programming - Chapter 14

References

Expose a variable to external linkage?

Description

header.nasm

global pi

section .data
    pi dq 3.141592

section .text
    ...

main.nasm>

extern pi

section .text
    ...

Resources

  • Beginning x64 Assembly Programming - Chapter 14

References

Inline Functions

Use an assembly function in a C source?
section .text
	global sum

sum:
    push rbp
    mov rbp, rsp

    mov rax, rdi
    add rax, rsi

    leave
    ret
nasm -f elf64 -g -F dwarf sum.asm
#include <stdio.h>

extern int sum(int, int);

int main(void)
{
    int result = sum(4, 2);
    printf("%i\n", result);
}
gcc -g -o program main.c sum.o
./program

Resources

  • Beginning x64 Assembly Programming - Chapter 22

References

How many of inline assembly types are available?

There are two types of inline assembly: basic and extended.

Compilers will not optimize assembly parts of the program, so using inline assembly is not advices. There will be no error checking on inline assembly code.


Resources

  • Beginning x64 Assembly Programming - Chapter 23

References

Write a basic inline assembly in C programs?

Description

Instructions should be terminated by ;. -mintel compiler option is required. Switching to Intel assembly syntax is required as the first argument of __asm__.

int main(void)
{
    __asm__(
        ".intel_syntax noprefix;"
        "xor rax, rax;"
    );
}
gcc -o program main.c -masm=intel -no-pie

Resources

  • Beginning x64 Assembly Programming - Chapter 23

References

Write extended inline assembly in C programs? (needs work)

General syntax of extended inline assembly is as follows:

__asm__(
    assembler code
    : output operands
    : input operands
    : list of clobbered registers
);
  • After the assembler code, additional and optional information is used.
  • Instruction orders must be respected.
__asm__(
    ".intel_syntax noprefix;"
    "mov rbx, rdx;"
    "imul rbx, rcx;"
    "mov rax, rbx;"
    :"=a"(eproduct)
    :"d"(x), "c"(y)
    :"rbx"
);

printf("The extended inline product is %i\n", eproduct);

a, d, c are register constraints, and they map to the registers rax, rdx, rcx, respectively. :"=a"(eproduct) means that the output will be in rax, and rax will refer to the variable eproduct. Register rdx refers to x, and rcx refers to y, which are the input variables. rbx is considered clobbered in the code and will be restored to its original value, because it was declared in the list of clobbering registers.

a -> rax, eax, ax, al
b -> rbx, ebx, bx, bl
c -> rcx, ecx, cx, cl
d -> rdx, edx, dx, dl
S -> rsi, esi, si
D -> rdi, edi, di
r -> any register

Resources

  • Beginning x64 Assembly Programming - Chapter 23

References

Macros

Use inline procedures to avoid runtime overhead of function calls?

Description

extern printf

; multiply value v by shifting it n times
%define multiply(v, n) sal v, n

; having two arguments
%macro print 2
    section .data
        %%detail db %1, 0
        %%format_string db "%s: %i", 10, 0
    section .text
        xor rax, rax
        mov rdi, %%format_string
        mov rsi, %%detail
        mov rdx, %2
        call printf
%endmacro

section .data
    number dq 42

section .text
    global main

main:
    push rbp
    mov rbp, rsp

    print "value is", number
    multiply(number, 2)
    print "multiplication result", number

    xor rax, rax
    leave
    ret

Resources

  • Beginning x64 Assembly Programming - Chapter 18

References

Conditionally compile a part of x64 assembly program?
section .data
    CONDITION equ 1

section .text
    global main

main:
    push rbp
    mov rbp, rsp

%IF CONDITION
    xor rdi, rdi
%ELSE
    mov rdi, 1
%ENDIF

    leave
    ret

Resources

  • Beginning x64 Assembly Programming - Chapter 20

References

Input/Output System Calls

Write into the standard output stream?

Description

section .text
    global write

; preconditions:
; address of string be set to rsi
; length of string be set to rdx
write:
    push rbp
    mov rbp, rsp

    mov rax, 1  ; write system call number
    mov rdi, 1  ; stdout
    syscall

    xor rax, rax
    leave
    ret

Resources

  • Beginning x64 Assembly Programming - Chapter 19

References

Read from the standard input stream?
section .text
    global read

; preconditions:
; address of buffer be set to rsi
; length of buffer be set to rdx
read:
    push rbp
    mov rbp, rsp

    mov rax, 0  ; read system call number
    mov rdi, 0  ; stdin

    xor rax, rax
    leave
    ret

Resources

  • Beginning x64 Assembly Programming - Chapter 19

References

Stack Overflow

Prevent stack overflow by counting input string before printing it?

Description

section .text
    global read

print:
    push rbp
    mov rbp, rsp

    push r12        ; callee saved

    xor rdx, rdx    ; character counter
    mov r12, rdi    ; string address

.counter:
    cmp byte[r12], 0
    je .print

    inc rdx
    inc r12
    jmp .counter

.print:
    cmp rdx, 0
    je .exit

    mov rsi, rdi    ; string address
                    ; rdx holds string length
    mov rax, 1      ; write
    mov rdi, 1      ; stdout
    syscall

.exit:
    pop r12
    xor rax, rax
    leave
    ret

Resources

  • Beginning x64 Assembly Programming - Chapter 19

References

Prevent stack overflows by limiting the maximum allowed input length from standard input?
section .text
    global read

; \pre rdi address of string placeholder
; \pre rsi maximum characters to read
; \post rax error code
read:
    section .data
        newline db 0xa

    section .bss
        .buffer resb 1      ; hold 1 character from input

    section .text
        push rbp
        mov rbp, rsp

        push r12            ; callee saved
        push r13            ; callee saved
        push r14            ; callee saved

        mov r12, rdi        ; input string address
        mov r13, rsi        ; max count
        xor r14, r14        ; character counter

    .read:
        mov rax, 0          ; read
        mov rdi, 1          ; stdin
        lea rsi, [.buffer]  ; input address
        mov rdx, 1          ; characters to read
        syscall

        mov al, [.buffer]   ; check if reached NL
        cmp al, byte[newline]
        je .check_exit

        cmp al, 97          ; check if input character is lower than 'a'
        jl .read            ; ignore this and read next character

        cmp al, 122         ; check if input character is greater than 'z'
        jg .read            ; ignore this and read next character

        inc r14             ; increment counter

        cmp r14, r13        ; check if number of characters reached maximum
        ja .read            ; don't put input charater into buffer
                            ; but keep reading from stdin to read newline

        mov byte[r12], al   ; put input character into buffer
        inc r12             ; point to next character placeholder in buffer
        jmp .read           ; read next input character

    .check_exit
        cmp r14, 0          ; check if anything was read
        ja .exit_success

        mov rax, 1          ; return 1 when failed to read anything
        jmp .exit

    .exit_success
        xor rax, rax        ; return 0 when read at least 0 character

    .exit
        inc r12             ; counter null character
        mov byte[r12], 0    ; close string by putting null at the end
        pop r14             ; restore for callee
        pop r13             ; restore for callee
        pop r12             ; restore for callee

        leave
        ret

Resources

  • Beginning x64 Assembly Programming - Chapter 19

References

Command Line Arguments

What registers are used to read command line arguments from an x64 assembly program?
  • rdi: argc or number of arguments
  • rsi: argv or address of array each, cell is an 8bytes of address to an argument string

Resources

  • Beginning x64 Assembly Programming - Chapter 21

References

Read command line arguments from an x64 assembly program?

Description

extern printf

section .data
    fmt db "%s", 10, 0

section .text
    global main

main:
    push rbp
    mov rbp, rsp

    mov r12, rdi
    mov r13, rsi
    xor r14, r14

.arg:
    mov rdi, fmt
    mov rsi, qword[r13 + r14 * 8]
    call printf

    inc r14
    cmp r14, r12
    jl .arg

    leave
    ret

Resources

  • Beginning x64 Assembly Programming - Chapter 21

References

Inspect the command line arguments stored in registers in a GNU debugger?
info registers rdi rsi rsp
x/1xg <the pointer in rdi>
x/s <address where the pointer in rdi points to>
x/s <address where the pointer in rdi points to + 8>
x/s <address where the pointer in rdi points to + 16>

Resources

  • Beginning x64 Assembly Programming - Chapter 21

References

File Operations

What header contains file operation constants?

/usr/include/asm-generic/fcntl.h


Resources

  • Beginning x64 Assembly Programming - Chapter 20

References

Open and close a file in x64 assembly?

Description

section .data
    CREATE equ 1            ; use for conditional assembly
    NR_create equ 85        ; create system call

section .text
    global create

; \pre rdi address of filename string
; \post rax error code
create:
    push rbp
    mov rbp, rsp

    mov rax, NR_create
    mov rsi, S_IRUSR | S_IWUSR
    syscall

    leave
    ret
section .data
    CREATE equ 1            ; use for conditional assembly
    NR_create equ 85        ; create system call

section .text
    global create

; \pre rdi file descriptor
; \post rax error code
create:
    push rbp
    mov rbp, rsp

    mov rax, NR_create
    mov rsi, S_IRUSR | S_IWUSR
    syscall

    leave
    ret
extern create
extern close

section .text
    global main

main:
    section .data
        fd dq 0                 ; to hold file descriptor

    section .text
        push rbp
        mov rbp, rsp

    %IF CREATE
        mov rdi, filename
        call create
        mov qword[fd], rax      ; save file descriptor
    %ENDIF

    %IF CLOSE
        mov rdi, qword[fd]      ; file descriptor
        call close
    %ENDIF

Resources

  • Beginning x64 Assembly Programming - Chapter 20

References

Write content to a file in x64 assembly?
section .data
    CREATE equ 1            ; use for conditional assembly

section .text
    global create

create:
    push rbp
    mov rbp, rsp

    leave
    ret
extern create
extern close
extern write

section .text
    global main

main:
    section .data
        fd dq 0                 ; to hold file descriptor

    section .text
        push rbp
        mov rbp, rsp

    %IF CREATE
        mov rdi, filename
        call create
        mov qword[fd], rax      ; save file descriptor
    %ENDIF

    %IF WRITE
        mov rdi, qword[fd]      ; file descriptor
        mov rsi, text           ; address of string
        mov rdx, qword[length]  ; length of string
        call write
    %ENDIF

    %IF CLOSE
        mov rdi, qword[fd]      ; file descriptor
        call close
    %ENDIF

Resources

  • Beginning x64 Assembly Programming - Chapter 20

References

Truncate a file in x64 assembly?

Description

section .data
    CREATE equ 1            ; use for conditional assembly

section .text
    global create

create:
    push rbp
    mov rbp, rsp

    leave
    ret
extern create
extern close
extern write

section .text
    global main

main:
    section .data
        fd dq 0                 ; to hold file descriptor

    section .text
        push rbp
        mov rbp, rsp

    %IF CREATE
        mov rdi, filename
        call create
        mov qword[fd], rax      ; save file descriptor
    %ENDIF

    %IF WRITE
        mov rdi, qword[fd]      ; file descriptor
        mov rsi, text           ; address of string
        mov rdx, qword[length]  ; length of string
        call write
    %ENDIF

    %IF CLOSE
        mov rdi, qword[fd]      ; file descriptor
        call close
    %ENDIF

Resources

  • Beginning x64 Assembly Programming - Chapter 20

References

Vector Registeres Support

Obtain the CPU information of the processor in x64 assembly?

Description

You first put a specific parameter in eax, then execute the instruction cpuid, and finally check the returned value in ecx and edx. Indeed, cpuid uses 32-bit registers.

Based on processor manual, SSE bits are as follows:

  • sse: edx:25
  • sse2: edx:26
  • sse3: ecx:1
  • ssse3: ecx:1 and ecx:8
  • sse4.1: ecx:19
  • sse4.2: ecx:20
section .text
    global main

main:
    push rbp
    mov rbp, rsp

    mov eax, 1
    cpuid

    leave
    ret

Resources

  • Beginning x64 Assembly Programming - Chapter 25

References

Check the processors which version of SSE extensions do they support?

Description

extern printf

section .data
    fmt_sse42 db "sse4_2", 10, 0
    fmt_sse41 db "sse4_1", 10, 0
    fmt_ssse3 db "ssse3", 10, 0
    fmt_sse3 db "sse3", 10, 0
    fmt_sse2 db "sse2", 10, 0
    fmt_sse db "sse", 10, 0
    fmt_sep db ",", 10, 0

section .text
    global main

main:
    push rbp
    mov rbp, rsp

    mov eax, 1
    cpuid
    mov r12, rcx      ; store the half result of cpuid
    mov r13, rdx      ; store the half result of cpuid

    call sse
    call sse2
    call sse3
    call ssse3
    call sse41
    call sse42

    xor rax, rax
    leave
    ret

sse:
    push rbp
    mov rbp, rsp

    ; call also be done with bt instruction: bt r13, 25
    test r13, 2000000h  ; test bit 25
    jz .sse_unsupported

    xor rax, rax
    mov rdi, fmt_sse
    call printf

.sse_unsupported:
    leave
    ret

sse2:
    push rbp
    mov rbp, rsp

    test r13, 4000000h  ; test bit 26
    jz .sse2_unsupported

    xor rax, rax
    mov rdi, fmt_sse2
    call printf

.sse2_unsupported:
    leave
    ret

sse3:
    push rbp
    mov rbp, rsp

    test r12, 1         ; test bit 0
    jz .sse3_unsupported

    xor rax, rax
    mov rdi, fmt_sse3
    call printf

.sse3_unsupported:
    leave
    ret

ssse3:
    push rbp
    mov rbp, rsp

    test r12, 9         ; test bit 0
    jz .ssse3_unsupported

    xor rax, rax
    mov rdi, fmt_ssse3
    call printf

.ssse3_unsupported:
    leave
    ret

sse41:
    push rbp
    mov rbp, rsp

    test r12, 80000h    ; test bit 19
    jz .sse41_unsupported

    xor rax, rax
    mov rdi, fmt_sse41
    call printf

.sse41_unsupported:
    leave
    ret

sse42:
    push rbp
    mov rbp, rsp
    test r12, 100000h   ; test bit 20
    jz .sse42_unsupported

    xor rax, rax
    mov rdi, fmt_sse42
    call printf

.sse42_unsupported:
    leave
    ret

Resources

  • Beginning x64 Assembly Programming - Chapter 25

References

How many registers of SSE are available on any processor supporting it?

Description

16 additional 128-bit registers of xmm:

  • xmm0
  • ...
  • xmm15

Resources

  • Beginning x64 Assembly Programming - Chapter 26

References


What are the two types of data that can be stored on SSE registers?

The xmm registers can contain scalar data or packed data.

Scalar data means just one value. Packed data means multiple values related to each other.


Resources

  • Beginning x64 Assembly Programming - Chapter 26

References

What are AVX registers and how much data can they hold?

The AVX registers are called ymm registers and have 256 bits, double the size of xmm registers.

There is also AVX-512 which provides 512 bits registers and are called zmm registers.


Resources

  • Beginning x64 Assembly Programming - Chapter 26

References

How does alignment of data in .data and .bss sections can improve performance of a program?

Data in section .data and .bss should be aligned on a 16-byte border so that registers can be filled with data once for each block of data.


Resources

  • Beginning x64 Assembly Programming - Chapter 26

References

How can we align data in .data and .bss sections in specific byte sizes?

Description

In NASM the assembly directive align 16 and alignb 16 can be used in front of the data.

For AVX, data should be aligned on a 32 bytes border and for AVX-512, data needs to be aligned on a 64 bytes border.


Resources

  • Beginning x64 Assembly Programming - Chapter 26

References