feat: sort the entries before printing them
This commit is contained in:
@@ -82,6 +82,12 @@ _start:
|
|||||||
@ r0 needs the fd, which it should already be since the call to open() set r0 to the fd.
|
@ 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
|
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.
|
@ TODO: we can allocate the required memory on the stack instead of in the bss section I think.
|
||||||
|
/*
|
||||||
|
TODO: this only reads up to 16KB of directory entries. if a directory we pass has entries with a sum larger
|
||||||
|
than 16KB then we don't end up printing those.
|
||||||
|
Solution: a nested loop. one for reading until the syscall returns 0 to indicate end of directory, and one for
|
||||||
|
looping the directories
|
||||||
|
*/
|
||||||
mov r2, #16384 @ how many bytes to read
|
mov r2, #16384 @ how many bytes to read
|
||||||
mov r7, #SYS_GETDENTS
|
mov r7, #SYS_GETDENTS
|
||||||
svc 0
|
svc 0
|
||||||
@@ -93,19 +99,14 @@ _start:
|
|||||||
|
|
||||||
mov r4, #0 @ initialize r4 to 0
|
mov r4, #0 @ initialize r4 to 0
|
||||||
ldr r5, =buffer
|
ldr r5, =buffer
|
||||||
|
|
||||||
|
sub sp, sp, #4096 @ allocate 4KB of mem to store the directory entries.
|
||||||
|
mov r1, sp
|
||||||
|
mov r10, #0 @ dir entry counter
|
||||||
1:
|
1:
|
||||||
push {r0}
|
add r2, r5, #10 @ offset 10 bytes into the dirent struct to reach d_name.
|
||||||
|
str r2, [r1, r10, lsl #2] @ store the value in r2 in the memory address pointed to by r1[r10 << 2]. The shift is just (r10 * 4)
|
||||||
add r1, r5, #10 @ offset 10 bytes into the dirent struct to reach d_name.
|
add r10, r10, #1
|
||||||
bl strlen
|
|
||||||
mov r2, r0
|
|
||||||
bl print
|
|
||||||
|
|
||||||
ldr r1, =NEWLINE
|
|
||||||
mov r2, #1
|
|
||||||
bl print
|
|
||||||
|
|
||||||
pop {r0}
|
|
||||||
|
|
||||||
@ load the value (as 16-bits zero-extended as opposed to loading 32-bits and then extending that ourselves with UXTH)
|
@ 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
|
@ in the memory address of r5 offset by 8 bytes to get us the d_reclen
|
||||||
@@ -117,6 +118,61 @@ _start:
|
|||||||
cmp r4, r0
|
cmp r4, r0
|
||||||
blt 1b
|
blt 1b
|
||||||
|
|
||||||
|
/* bubble sort
|
||||||
|
TODO: improvements:
|
||||||
|
- a case-insensitive strcmp should be used when sorting
|
||||||
|
- dots at the beginning of a file name should be ignored when sorting/comparing to match ls' behavior
|
||||||
|
*/
|
||||||
|
mov r5, r1 @ save the array pointer in r5 because we'll be using r1 a lot
|
||||||
|
mov r3, #0 @ outer loop counter
|
||||||
|
outer:
|
||||||
|
mov r4, #0 @ inner loop counter
|
||||||
|
sub r8, r10, r3
|
||||||
|
sub r8, r8, #1
|
||||||
|
push {r3}
|
||||||
|
|
||||||
|
inner:
|
||||||
|
ldr r1, [r5, r4, lsl #2]
|
||||||
|
add r6, r4, #1
|
||||||
|
ldr r2, [r5, r6, lsl #2]
|
||||||
|
push {r1-r2}
|
||||||
|
bl strcmp_ascii
|
||||||
|
pop {r1-r2}
|
||||||
|
|
||||||
|
cmp r0, #1
|
||||||
|
bne 2f
|
||||||
|
@ swap if a > b
|
||||||
|
mov r7, r1
|
||||||
|
str r2, [r5, r4, lsl #2]
|
||||||
|
str r7, [r5, r6, lsl #2]
|
||||||
|
|
||||||
|
2:
|
||||||
|
add r4, r4, #1
|
||||||
|
cmp r4, r8
|
||||||
|
blt inner
|
||||||
|
|
||||||
|
pop {r3}
|
||||||
|
add r3, r3, #1
|
||||||
|
cmp r3, r10
|
||||||
|
blt outer
|
||||||
|
|
||||||
|
print_entries:
|
||||||
|
ldr r1, [r5], #4
|
||||||
|
bl bytelen
|
||||||
|
|
||||||
|
mov r2, r0
|
||||||
|
bl print
|
||||||
|
|
||||||
|
ldr r1, =NEWLINE
|
||||||
|
mov r2, #1
|
||||||
|
bl print
|
||||||
|
|
||||||
|
sub r10, r10, #1
|
||||||
|
cmp r10, #0
|
||||||
|
bgt print_entries
|
||||||
|
|
||||||
|
add sp, sp, #4096
|
||||||
|
|
||||||
mov r0, #0
|
mov r0, #0
|
||||||
bl exit
|
bl exit
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
/*
|
/*
|
||||||
Current implementation only counts the bytes instead of characters.
|
|
||||||
|
|
||||||
@args:
|
@args:
|
||||||
r1 => pointer to the string
|
r1 => pointer to the string
|
||||||
@returns:
|
@returns:
|
||||||
@@ -8,7 +6,7 @@
|
|||||||
@clobbers:
|
@clobbers:
|
||||||
r2
|
r2
|
||||||
*/
|
*/
|
||||||
strlen:
|
bytelen:
|
||||||
mov r0, #0
|
mov r0, #0
|
||||||
1:
|
1:
|
||||||
ldrb r2, [r1, r0]
|
ldrb r2, [r1, r0]
|
||||||
@@ -19,7 +17,32 @@ strlen:
|
|||||||
b 1b
|
b 1b
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@input r1, r2 - pointers to the strings to compare
|
@args:
|
||||||
@return r0 - 0 if equal, -1 if a < b, 1 if a > b
|
r1 => pointer to first string
|
||||||
|
r2 => pointer to second string
|
||||||
|
@returns:
|
||||||
|
r0 => 0 if equal, -1 if a < b, 1 if a > b
|
||||||
|
@clobbers:
|
||||||
|
r1, r2, r3
|
||||||
*/
|
*/
|
||||||
strcmp: @ TODO: implement
|
strcmp_ascii:
|
||||||
|
@ comparison loop
|
||||||
|
1:
|
||||||
|
ldrb r0, [r1], #1
|
||||||
|
ldrb r3, [r2], #1
|
||||||
|
cmp r0, r3
|
||||||
|
bne 2f
|
||||||
|
cmp r0, #0
|
||||||
|
bne 1b
|
||||||
|
|
||||||
|
@ strings are equal
|
||||||
|
mov r0, #0
|
||||||
|
bx lr
|
||||||
|
|
||||||
|
@ if we found a different byte then return the appropriate integer
|
||||||
|
2:
|
||||||
|
sub r0, r0, r3
|
||||||
|
cmp r0, #0
|
||||||
|
movlt r0, #-1
|
||||||
|
movgt r0, #1
|
||||||
|
bx lr
|
||||||
|
|||||||
Reference in New Issue
Block a user