summaryrefslogtreecommitdiff
path: root/PGU/CHAP6_7/modify-records.s
blob: 4cf2d9217d6fab9ffef1bd83560c010dc61aaac0 (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
# Modify records in a file and write them to the output file
.include "linux.s"
.include "record-def.s"

.section .data
	input_filename:
		.ascii "test.dat\0"
	output_filename:
		.ascii "modified.dat\0"

.section .bss
	.lcomm record_buffer, RECORD_SIZE


.section .text
.globl _start

_start:
	# Stack local vars
	.equ ST_INPUT_DESCRIPTOR, -8
	.equ ST_OUTPUT_DESCRIPTOR, -16

	# Copy stack pointer and make room for local variables
	movq %rsp, %rbp
	subq $16, %rsp

	# Open file for reading
	movq $SYS_OPEN, %rax
	movq $input_filename, %rdi
	movq $0, %rsi
	movq $0666, %rdx
	syscall

	cmpq $0, %rax
	jl continue_processing

	# We've got an error...
continue_processing:
	movq %rax, ST_INPUT_DESCRIPTOR(%rbp)

	.section .data
		no_open_file_code:
			.ascii "0001: \0"
		no_open_file_msg:
			.ascii "Can't open input file\0"
	.section .text
		pushq $no_open_file_msg
		pushq $no_open_file_code
		call error_exit

	# Open file for writing
	movq $SYS_OPEN, %rax
	movq $output_filename, %rdi
	movq $0101, %rsi
	movq $0666, %rdx
	syscall

	movq %rax, ST_OUTPUT_DESCRIPTOR(%rbp)

loop_begin:
	pushq ST_INPUT_DESCRIPTOR(%rbp)
	pushq $record_buffer
	call read_record
	addq $16, %rsp

	# Return number of bytes read. If it's not the same as
	# $RECORD_SIZE, then we are either at EOF or we hit an error.
	cmpq $RECORD_SIZE, %rax
	jne loop_end

	# Increment age...
	incq record_buffer + RECORD_AGE

	# Write record to the output file
	pushq ST_OUTPUT_DESCRIPTOR(%rbp)
	pushq $record_buffer
	call write_record
	addq $16, %rsp

	jmp loop_begin

loop_end:

	movq $SYS_EXIT, %rax
	movq $0, %rbx
	syscall