From f627ab2ec60b2b861a6adb22f7d66429439ef601 Mon Sep 17 00:00:00 2001 From: Tijmen van Nesselrooij Date: Sun, 10 Mar 2019 12:17:59 +0100 Subject: [PATCH] x86_64 added --- x86_64/0_basic.asm | 117 +++++++++++++++++++++++++++++++++++++++++++++ x86_64/README.md | 15 ++++++ x86_64/debug.sh | 22 +++++++++ x86_64/makefile | 21 ++++++++ 4 files changed, 175 insertions(+) create mode 100644 x86_64/0_basic.asm create mode 100644 x86_64/README.md create mode 100644 x86_64/debug.sh create mode 100644 x86_64/makefile diff --git a/x86_64/0_basic.asm b/x86_64/0_basic.asm new file mode 100644 index 0000000..b06ee22 --- /dev/null +++ b/x86_64/0_basic.asm @@ -0,0 +1,117 @@ +global _start + +; !! THIS IS INTEL STYLE ASSEMBLY !! + +section .data + ; This is an array, db = declare bytes + my_arr: db 0x12,0x34,0x56,0x78,0x90 + + ; Some basic types: + ; byte = 8 bits + ; word = 16 bits + ; double word = dword = 32 bits + ; quad word = qword = 64 bits + + ; To declare them: + ; db + ; dw + ; dd + ; dq + + ; Endianness examples, this will be stored in reverse + ; e.g. 0xbeef -> 0xef 0xbe in memory + little_endian: dw 0xbeef + + ; Supplying not enough bytes means the remainder will be zero filled + zerod_remainder: dw 0x42 ; = 0x42 0x00 in memory + + ; Equ works like #define + ; It does get a symbol however, and can thus be used by other + ; assemblies (by making it global). This value gets inlined. + ; Useful for constant expressions + PI: equ 3 + +section .text + +; Entry point +_start: + ; Move 0 into the register RAX (64 bits) + mov rax, 0 + + ; General purpose registers (A, B, C, D, ...) + ; rax = accumulator + ; rbx = base + ; rcx = counter + ; rdx = destination + ; rsp & rbp = stack pointer (sp) and base pointer(bp) + ; rsi & rdi = source index (si) and destination index (di) + ; r8 - r15 = plain old registers + + ; Note that for all registers except the r8-r15 speficic bits + ; can be addressed by changing the prefix and postfix, e.g. + ; for register A: rax, eax, ax, al and ah + + mov eax, 0xdeadbeef ; Copy 32 bits, 4 bytes, 1 dword + mov ebx, 0xabcd ; = mov ebx, 0x0000abcd + mov cl, 0xFF + mov ch, 0x00 + ; ecx = 0x00FF + + ; Some basic arithmetic + mov rdi, 10 + mov rsi, 7 + mov rbx, 14 + + inc rdi ; increment + dec rsi ; decrement + + ; note: operator dest, src + add rdi, rbx ; stores the ADD result in the first operand (rdi) + sub rsi, rbx ; rsi = rsi - rbx + + ; By default all arithmetic assumes unsigned values. Prepend with I to + ; use signed math (e.g. imul, idiv, etc.) + + ; Multiplication + ; Yields 128 bit values + ; It multiplies the operand with the value of register A + ; Stores the lower 64 bits in register A and the upper 64 bits in + ; Register D + mov rax, 7 + mov rdx, 4 + mov rdi, 3 + mul rdi ; rax = rax * rdi, rdx = 0 (because no overflow) + + ; Division + ; Yields a 128 bit value + ; The result (64 bits) is stored in register A + ; The remainder (64 bits) is stored in register D + mov rax, 22 ; divident, to be result + mov rdx, 0 ; to be remainder + mov rdi, 5 ; divider + + div rdi ; rax = 22/5 = 4, rdx = 2 + + ; Bitwise operations + ; AND + ; OR + ; XOR + ; SHR + ; SHL + + mov rdi, 0x35 + mov rsi, 0x44 + + and rdi, rsi + or rdi, rsi + xor rdi, rsi + + shr rsi, 2 ; rsi >> 2 + shl rsi, 3 ; rsi << 3 + + ; There is also SAL and SAR for arithmetic left- and right shifts + + mov rax, 60 + xor rdi, rdi ; zero it + syscall + diff --git a/x86_64/README.md b/x86_64/README.md new file mode 100644 index 0000000..d11f550 --- /dev/null +++ b/x86_64/README.md @@ -0,0 +1,15 @@ +# Build steps + +## Assembling +Assembling with NASM +```bash +nasm -g -f elf64 +``` +- g = include debug info +- f = file format (elf64 -> x64) + +## Linking +```bash +ld -o # Default +gcc -o # When using C library functions +``` diff --git a/x86_64/debug.sh b/x86_64/debug.sh new file mode 100644 index 0000000..6f7176f --- /dev/null +++ b/x86_64/debug.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +if [ -z "$1" ]; then + echo "Provide the program to debug as first argument" + exit 1 +fi + +if [ ! -x "$1" ]; then + echo "$1 is not an executable file" + exit 1 +fi + +echo "I will launch gdbtui soon. Use \"break *\" to debug the program." +echo "Use \"layout asm\" to use a more assembly friendly layout" +echo "Use \"si\" to single step each instruction" +echo "" + +echo "$(readelf -h $1 | egrep "Entry point")" +read -p "Copy the above address and press any key to continue..." + +gdbtui -q $1 + diff --git a/x86_64/makefile b/x86_64/makefile new file mode 100644 index 0000000..7fde932 --- /dev/null +++ b/x86_64/makefile @@ -0,0 +1,21 @@ +CC = gcc +AS = nasm +LD = ld + +.PHONY: all clean + +all: build 0_basic + +clean: + -rm -r build + -rm 0_basic + +build: + mkdir build + +build/%.o: %.asm + $(AS) -g -f elf64 $< -o $@ + +0_basic: build/0_basic.o + $(LD) $< -o $@ +