diff options
author | Gentoo <installgentoo@endianness.com> | 2020-10-28 13:35:32 +1100 |
---|---|---|
committer | Gentoo <installgentoo@endianness.com> | 2020-10-28 13:35:32 +1100 |
commit | 2f5888e7cd4503698280282b15117736f166c19e (patch) | |
tree | b516750eb76965fcddc3fd3ce1e04db94e881e16 /cat.asm | |
download | cat-asm-2f5888e7cd4503698280282b15117736f166c19e.tar.gz cat-asm-2f5888e7cd4503698280282b15117736f166c19e.tar.bz2 cat-asm-2f5888e7cd4503698280282b15117736f166c19e.zip |
initial commit
Diffstat (limited to 'cat.asm')
-rw-r--r-- | cat.asm | 100 |
1 files changed, 100 insertions, 0 deletions
@@ -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 |