summaryrefslogtreecommitdiff
path: root/PGU/CHAP9/read-records.s
diff options
context:
space:
mode:
Diffstat (limited to 'PGU/CHAP9/read-records.s')
-rw-r--r--PGU/CHAP9/read-records.s86
1 files changed, 86 insertions, 0 deletions
diff --git a/PGU/CHAP9/read-records.s b/PGU/CHAP9/read-records.s
new file mode 100644
index 0000000..01384a0
--- /dev/null
+++ b/PGU/CHAP9/read-records.s
@@ -0,0 +1,86 @@
+# Read records previously written in file.dat, by write-records software
+
+.include "linux.s"
+.include "record-def.s"
+
+.section .data
+ filename:
+ .ascii "test.dat\0"
+ record_buffer_ptr:
+ .long 0
+
+.section .text
+
+.globl _start
+
+_start:
+ # Stack locations for INPUT and OUTPUT FDs
+ .equ ST_INPUT_DESCRIPTOR, -8
+ .equ ST_OUTPUT_DESCRIPTOR, -16
+
+ movq %rsp, %rbp
+ subq $16, %rsp # Save space in the stack for FDs
+
+ call allocate_init # Initialize our memory
+
+ # allocate buffer
+ pushq $RECORD_SIZE
+ call allocate
+ movq %rax, record_buffer_ptr
+
+ # Open data file
+ movq $SYS_OPEN, %rax
+ movq $filename, %rdi
+ movq $0, %rsi # Open for read only
+ movq $0666, %rdx
+ syscall
+
+ # Save FD
+ movq %rax, ST_INPUT_DESCRIPTOR(%rbp)
+
+ # Yes, STDOUT is always 1, but if I want to change the output location
+ # later, I don't need to change everywhere...
+ movq $STDOUT, ST_OUTPUT_DESCRIPTOR(%rbp)
+
+record_read_loop:
+ pushq ST_INPUT_DESCRIPTOR(%rbp)
+ pushq record_buffer_ptr
+ call read_record
+ addq $16, %rsp # Cleanup stack
+
+ # All records are RECORD_SIZE size, if we didn't get this amount of
+ # bytes from read function, we either are at EOF or we hit an error.
+ cmpq $RECORD_SIZE, %rax
+ jne finished_reading
+
+ # We are ok, so print the first name in the record
+ movq record_buffer_ptr, %rax
+ addq $RECORD_FIRSTNAME, %rax # Seek offset of the firstname in the
+ # buffer
+ pushq %rax
+ call count_chars
+ addq $8, %rsp # Cleanup stack
+
+ # Write name to OUTPUT
+ movq %rax, %rdx # Returned record size, used as argument to
+ # write()
+
+ movq record_buffer_ptr, %rsi
+ addq $RECORD_FIRSTNAME, %rsi
+ movq ST_OUTPUT_DESCRIPTOR(%rbp), %rdi
+ movq $SYS_WRITE, %rax
+ syscall
+
+ pushq ST_OUTPUT_DESCRIPTOR(%rbp)
+ call write_newline
+ addq $8, %rsp
+
+ jmp record_read_loop
+
+ # Free buffer
+ pushq record_buffer_ptr
+ call deallocate
+finished_reading:
+ movq $SYS_EXIT, %rax
+ movq $0, %rdi
+ syscall