From afab4501d6c77b12aa2221c765bdb2c705d588a7 Mon Sep 17 00:00:00 2001 From: Hisham Aburaqibah Date: Mon, 18 Aug 2025 22:10:48 +0200 Subject: [PATCH] initial commit --- main.S | 132 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 132 insertions(+) create mode 100644 main.S diff --git a/main.S b/main.S new file mode 100644 index 0000000..5e7a784 --- /dev/null +++ b/main.S @@ -0,0 +1,132 @@ +.global _start + +exit: + @ Exit the program with a status code of 0 + @mov r0, #0 @ `exit` syscall requires the status code to be written to r0 + mov r7, #1 @ `exit` syscall's number is 1. Move it to r7 (which is the register svc reads to know which syscall to execute) + svc 0 @ execute the syscall + +print: @ r1 => buffer to print. r2 => how many bytes to print + @ print to stdout + mov r0, #1 @ Use STDOUT fd as the write fd + mov r7, #4 @ call write(2) + svc 0 + bx lr @ return to caller + +fail: + @ push the result of open() onto the stack before calling print() + push {r0} + ldr r1, =OPEN_FAIL + mov r2, #31 + bl print + pop {r0} + + @mov r0, #1 + bl exit + +open_and_read_file: + @ open file + ldr r0, =FILE @ filepath + mov r1, #0 @ flags + mov r2, #0 @ mode_t + mov r7, #5 + svc 0 + + cmp r0, #0 + blt fail + + @ read the file contents + @ r0 needs the fd, which it should already be since the call to open() set r0 to the fd. + ldr r1, =buffer @ pointer to buffer to read into + mov r2, #50 @ how many bytes to read + mov r7, #3 + svc 0 + + @ print the contents of the buffer + ldr r1, =buffer + mov r2, #50 + bl print + + ldr r1, =NEWLINE + mov r2, #1 + bl print + + mov r0, #0 + bl exit + +strlen: + mov r0, #0 +strlen_loop: + ldrb r2, [r1, r0] + cmp r2, #0 + bxle lr + + add r0, r0, #1 + b strlen_loop + +direntry_loop: + cmp r4, r8 + bxge lr + + push {lr} + + add r1, r5, #10 @ offset 10 bytes into the dirent struct to reach d_name. + bl strlen + mov r2, r0 + bl print + + ldr r1, =NEWLINE + mov r2, #1 + bl print + + pop {lr} + + @ load the value (as 16-bits zero-extended as opposed to loading 32-bits and then extending that ourselves with UXTH) + @ in the memory address of r5 offset by 8 bytes to get us the d_reclen + ldrh r6, [r5, #8] + add r5, r5, r6 @ skip to the next dirent + + add r4, r4, r6 @ accumulate how many bytes we read + + b direntry_loop + +@ TODO: read args +@ TODO: if no arg passed, use current directory. +_start: + @ open file + ldr r0, =DIR @ filepath + mov r1, #0 @ flags + mov r2, #0 @ mode_t + mov r7, #5 + svc 0 + + cmp r0, #0 + blt fail + + @ read the directory contents + @ r0 needs the fd, which it should already be since the call to open() set r0 to the fd. + ldr r1, =buffer @ pointer to linux_dirent structure + @ TODO: we can allocate the required memory on the stack instead of in the bss section I think. + mov r2, #16384 @ how many bytes to read + mov r7, #0x8d @ getdents(2) + svc 0 + + mov r8, r0 @ store how many bytes the getdents syscall read, so we can use that to exit the direntry loop + mov r4, #0 @ initialize r4 to 0 + ldr r5, =buffer + bl direntry_loop + + mov r0, #0 + bl exit + +.data + FILE: .asciz "/home/hisham/asm.txt" + DIR: .asciz "/home/hisham" + OPEN_FAIL: .ascii "Failed to open file descriptor\n" + NEWLINE: .ascii "\n" + +.bss +buffer: + .skip 16384 +name: + .skip 256