summaryrefslogtreecommitdiff
path: root/PGU/CHAP6_7/read-records.s
blob: 89b1e91d47fe5aa3bbeb9f239427091d095f3e0e (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
# 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"

.section .bss
	.lcomm record_buffer, RECORD_SIZE

.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

	# 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
	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
	pushq $RECORD_FIRSTNAME + record_buffer		# Location of firstname
							# record in the buffer
							# we just read
	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_FIRSTNAME + record_buffer, %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

finished_reading:
	movq $SYS_EXIT, %rax
	movq $0, %rdi
	syscall