summaryrefslogtreecommitdiff
path: root/PGU/CHAP9/read-records.s
blob: 01384a0ea57a28396c91f4a918ce97a33cd4cbad (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
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