-
Notifications
You must be signed in to change notification settings - Fork 2
/
add-year-error-exit.asm
120 lines (99 loc) · 2.64 KB
/
add-year-error-exit.asm
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
%include "xnu.asm"
%include "record-def.asm"
extern error_exit
extern read_record
extern write_record
section .data
input_file_name:
; Null-terminated string as the user_addr_t path parameter of
; the open syscall
db 'test.dat', 0
output_file_name:
db 'testout.dat', 0
age:
dw 0
section .bss
record_buffer:
resb RECORD_SIZE
section .text
global start
start:
; These are the locations on the stack
; we will store the input and output descriptors
; (FYI - we could have used memory addresses in
; a .data section instead)
ST_INPUT_DESCRIPTOR equ -8
ST_OUTPUT_DESCRIPTOR equ -16
; Copy the stack pointer to rbp
mov rbp, rsp
; Allocate space to store the file descriptors
sub rsp, 16
; Open the input file
mov rax, SYS_OPEN
lea rdi, [rel input_file_name]
mov rsi, O_RDONLY
mov rdx, 0666
syscall
; Test in book is whether rax is negative.
; I'm actually checking if rax (the file descriptor number) is greater than 2
; since 2 represents STDERR.
; If the condition holds, it will jump to continue_processing.
; Otherwise it will handle the error condition that the invalid number represents
cmp rax, 2
jg continue_processing
; Send the error
section .data
no_open_file_code:
db '0001: ', 0
no_open_file_message:
db `Can't Open Input File`, 0
section .text
lea rdi, [rel no_open_file_message]
push rdi
lea rdi, [rel no_open_file_code]
push rdi
call error_exit
continue_processing:
; Save the file descriptor
mov [rbp + ST_INPUT_DESCRIPTOR], rax
; Open the output file
mov rax, SYS_OPEN
lea rdi, [rel output_file_name]
mov rsi, 0101
mov rdx, 0666
syscall
; @lmartinho: Check if open was successful
cmp rax, 2
je exit_failed_open
; Save the file descriptor
mov [rbp + ST_OUTPUT_DESCRIPTOR], rax
record_read_loop:
push qword [rbp + ST_INPUT_DESCRIPTOR]
lea rdi, [rel record_buffer]
push rdi
call read_record
add rsp, 16
; Returns the number of bytes read.
; If it isn't the same number we
; requested, then it's either an
; end-of-file, or an error, so we're
; quitting
cmp rax, RECORD_SIZE
jne finished_reading
; Increment the age, in place
inc dword [rel record_buffer + RECORD_AGE]
; Write the record to disk
push qword [rbp + ST_OUTPUT_DESCRIPTOR]
lea rdi, [rel record_buffer]
push rdi
call write_record
add rsp, 16
jmp record_read_loop
finished_reading:
mov rax, SYS_EXIT
mov rdi, 0
syscall
exit_failed_open:
mov rax, SYS_EXIT
mov rdi, 254
syscall