From 96391dd93c3013e9ff7591e5a20187fe76105a4e Mon Sep 17 00:00:00 2001 From: Tijmen van Nesselrooij Date: Wed, 13 Mar 2019 19:54:05 +0100 Subject: [PATCH] memory added --- x86_64/1_stdio.asm | 3 ++ x86_64/2_homework.asm | 51 +++++++++++++++++++++++++ x86_64/2_memory.asm | 88 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 142 insertions(+) create mode 100644 x86_64/2_homework.asm create mode 100644 x86_64/2_memory.asm diff --git a/x86_64/1_stdio.asm b/x86_64/1_stdio.asm index 3eb7dfb..f062c6f 100644 --- a/x86_64/1_stdio.asm +++ b/x86_64/1_stdio.asm @@ -22,6 +22,9 @@ _start: ; x64 has the syscall function, in contrast to int in x86 and ARM ; See /usr/include/asm/unistd_64.h for the numbers + ; Clobbered registers + ; rax rdi rsi rdx r10 r8 r9 + ; Write to stdout mov rax, 1 mov rdi, stdout ; fd to write to diff --git a/x86_64/2_homework.asm b/x86_64/2_homework.asm new file mode 100644 index 0000000..9c1b35a --- /dev/null +++ b/x86_64/2_homework.asm @@ -0,0 +1,51 @@ +global _start ; entry point label +section .data + str: db "Please give me a string: " ; \n = 0xA + strSize: equ $ - str + + stdin: equ 0 ; POSIX + stdout: equ 1 ; POSIX + +section .bss + strBuffer: resb 64 ; reserve 64 bytes + strBufferSize: equ 64 ; same as above + +section .text + ; Syscall clobbered registers + ; rax rdi rsi rdx r10 r8 r9 +_start: + mov rax, 1 + mov rdi, stdout ; fd to write to + mov rsi, str ; pointer + mov rdx, strSize ; size + syscall + + xor rax, rax ; 0 + mov rdi, stdin ; fd to read from + mov rsi, strBuffer ; where to store it + mov rdx, strBufferSize ; maximum number of bytes + syscall + + mov rbx, rax ; store the read bytes + + ; Calculate the halfway point of read bytes + dec rax ; subtract the read newline from it + xor rdx, rdx ; clear high bits dividend + ; rax is already set + mov rdi, 2 ; set the divisor + div rdi ; rax = rax / rdi + + ; Alter the middle byte + mov rdx, strBuffer + add rdx, rax + mov byte [rdx], '_' + + mov rax, 1 + mov rdi, stdout ; fd to write to + mov rsi, strBuffer ; pointer + mov rdx, rbx ; size + syscall + + mov rax, 60 + xor rdi, rdi + syscall \ No newline at end of file diff --git a/x86_64/2_memory.asm b/x86_64/2_memory.asm new file mode 100644 index 0000000..8ab8470 --- /dev/null +++ b/x86_64/2_memory.asm @@ -0,0 +1,88 @@ +global _start + +section .data + str: db '0123456789',0xA + strSize: equ $ - str + stdout: equ 1 + +section .text +_start: + ; Print the string + mov rdx, strSize + mov rsi, str + mov rdi, stdout + mov rax, 1 + syscall + + ; mov byte [rsi], 3 == *rsi = 3 + ; Move the value of 3 into the address contained in register RSI + ; Note the type specifier + ; byte, word, dword + + ; The official syntax is + ;mov byte ptr [rsi], 3 + ; But the ptr is implicitly meant with the []'s, so nasm allows + ; us to leave it out + + + mov byte [rsi], 'a' + mov rax, 1 + syscall + + mov word [rsi], 'bc' + mov rax, 1 + syscall + + mov dword [rsi], 'defg' + mov rax, 1 + syscall + + ; "In 64-bit mode, a memory operand can be referenced by + ; a segment selector and an offset. [...] + ; The offset part of a memory address in 64-bit mode can be + ; specified directly as a static value or through an address + ; computation made up of one or more of the following components: + ; Displacement -- An 8-bit, 16-bit, or 32-bit value. + ; Base -- The value in a 64-bit general-purpose register. + ; Index -- The value in a 64-bit general-purpose register. + ; Scale factor -- A value of 2, 4, or 8 that is multiplied + ; by the index value." + ; In intel syntax, this is written as: + ; [base + scale * index + displacement] + ; Example: + ; [rax + 2 * rbx + 0xdeadbeef] + ; (most of these are optional; see below). + + mov byte [rsi], 'h' ; base only + mov rax, 1 + syscall + + mov byte [str], 'i' ; displacement only + mov byte [str+1], 'j' ; displacement only too (assembler evaluates it) + mov rax, 1 + syscall + + mov rbx, 3 + mov byte [rsi+2], 'k' + mov byte [rsi+rbx], 'l' + mov byte [rsi+2*rbx], 'm' + mov byte [rsi+2*rbx+2], 'n' + mov rax, 1 + syscall + + ; Load Effective Address + ; Calculate the address of the expression, it does NOT load the value! + mov rbx, 2 + lea rsi, [str+2*rbx] ; = rsi = str + (2 * 2) + + ; Due to this powerful feature it is often used with invalid + ; addresses: you can use it to do generic calculations! + mov rbx, -2 + lea rdx, [strSize+2*rbx] ; print (strSize - 4) characters + mov rax, 1 + syscall + + ; Exit + mov rax, 60 + xor rdi, rdi + syscall