summaryrefslogtreecommitdiffstats
path: root/cat.asm
diff options
context:
space:
mode:
authorGentoo <installgentoo@endianness.com>2020-10-28 13:35:32 +1100
committerGentoo <installgentoo@endianness.com>2020-10-28 13:35:32 +1100
commit2f5888e7cd4503698280282b15117736f166c19e (patch)
treeb516750eb76965fcddc3fd3ce1e04db94e881e16 /cat.asm
downloadcat-asm-2f5888e7cd4503698280282b15117736f166c19e.tar.gz
cat-asm-2f5888e7cd4503698280282b15117736f166c19e.tar.bz2
cat-asm-2f5888e7cd4503698280282b15117736f166c19e.zip
initial commit
Diffstat (limited to 'cat.asm')
-rw-r--r--cat.asm100
1 files changed, 100 insertions, 0 deletions
diff --git a/cat.asm b/cat.asm
new file mode 100644
index 0000000..abd7144
--- /dev/null
+++ b/cat.asm
@@ -0,0 +1,100 @@
+; Version : 1.0
+; Updated : 28/10/2020
+; Description : Cat(1) in assembly
+; Licence : GPLv3
+
+section .bss
+ Buff resb 16384 ;read data up to 16384 bytes at a time
+ bufflen equ $-Buff
+
+section .data
+
+section .text
+ global _start
+_start:
+pop rsi ;Pop number of args from the stack
+
+cmp esi,1
+je stdin ;go to stdin mode if there are no arguments
+
+pop rsi ;discard argv[0]
+
+nextarg:
+pop rsi ;get pointer to argv[x]
+
+; we could use argc as a loop counter, but we can just check to see if we popped a zero intead
+test rsi, rsi
+jz exit
+
+; open each file for reading
+open:
+ mov eax, 2 ;sys_open
+ mov rdi, rsi ;filename = pointer to null terminated filename
+ xor esi, esi ;O_RDONLY
+ xor edx, edx ;don't set a mode
+ syscall
+
+ ; the result is returned in rax
+ test rax, rax
+ js nextarg ;get the next argv if rax is negative (as the file couldn't be opened)
+
+copy:
+ mov edi, eax ;move the fd to rdi for read
+ mov r15, rax ;copy the fd to an AMD64 addittional register for safekeeping
+ call read
+
+output:
+ mov edi, 1 ;stdout
+ mov edx, eax ;rax contains the number of bytes read
+ call write
+
+ mov ecx, eax ;copy the amount written to a different register
+ mov rax, r15 ;copy the fd back to rax
+
+ test ecx, bufflen ;check if all the bytes in the buffer have been used
+ jnz copy ;if so, jump to copy the remaining bytes not read into the buffer yet
+
+close:
+ mov rdi, r15 ;move fd into rdi
+ mov eax, 3 ;sys_close
+ syscall
+
+ jmp nextarg
+
+
+
+
+stdin:
+ xor edi, edi ;stdin == 0
+ call read
+
+ test eax,eax ; Check if the return value was 0
+ je exit ; Jump to exit on EOF recieved
+
+ mov edi, 1 ;file descriptor = stdout
+ mov edx, eax ;move num bytes read to number of bytes to write
+ call write
+
+ jmp stdin
+
+
+
+; read function, takes rdi as an argument (a fd)
+read:
+ mov edx, bufflen ;read up to bufflen bytes at once
+ mov rsi, Buff ;Address of buffer to read into
+ xor eax, eax ;sys_read
+ syscall
+ ret
+
+; write function, takes rdi as an argument (a fd) and also rdx (number of bytes)
+write:
+ mov rsi, Buff ;mov address of buffer
+ mov eax, 1 ;sys_write
+ syscall
+ ret
+
+exit:
+ xor edi, edi ; exit status == 0
+ mov eax, 60 ; SYSCALL number for EXIT
+ syscall