forked from lmartinho/pgubook-macos-x86-64
-
Notifications
You must be signed in to change notification settings - Fork 0
/
read-records.asm
97 lines (80 loc) · 2.32 KB
/
read-records.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
%include "xnu.asm"
%include "record-def.asm"
extern count_chars
extern read_record
extern write_newline
section .data
file_name:
; Null-terminated string as the user_addr_t path parameter of
; the open syscall
db 'test.dat', 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 file
mov rax, SYS_OPEN
lea rdi, [rel file_name]
mov rsi, O_RDONLY
mov rdx, 0666
syscall
; @lmartinho: Check if open was successful
cmp rax, 2
je exit_failed_open
; Save the file descriptor
mov [rbp + ST_INPUT_DESCRIPTOR], rax
; Even though it's a constant, we are
; saving the output file descriptor in a local
; variable so that if we later
; decide that it isn't always going to
; be STDOUT, we can change it easily.
mov qword [rbp + ST_OUTPUT_DESCRIPTOR], STDOUT
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
; Otherwise print out the first name
; but first, we must know its size
lea rdi, [rel record_buffer + RECORD_FIRSTNAME]
push rdi
call count_chars
add rsp, 8
; user_ssize_t write(int fd, user_addr_t cbuf, user_size_t nbyte)
mov rdi, [rbp + ST_OUTPUT_DESCRIPTOR] ; fd
lea rsi, [rel record_buffer + RECORD_FIRSTNAME] ; cbuf
mov rdx, rax ; nbyte
mov rax, SYS_WRITE ; write
syscall
push qword [rbp + ST_OUTPUT_DESCRIPTOR]
call write_newline
add rsp, 8
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