Files
ls-arm/main.S
T

133 lines
2.9 KiB
ArmAsm
Raw Normal View History

2025-08-18 22:10:48 +02:00
.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