-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsystem.inc
177 lines (139 loc) · 2.52 KB
/
system.inc
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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
; File descriptors
%define stdin 0
%define stdout 1
%define stderr 2
; name for each syscall
%define SYS_nosys 0
%define SYS_exit 1
%define SYS_fork 2
%define SYS_read 3
%define SYS_write 4
section .text
align 4
; for local use by syscall macros
access.the.kernel:
int 80h
ret
access.the.linux.kernel:
push rbx
mov rbx, [rsp+16]
push rcx
mov rcx, [rsp+32]
push rdx
mov rdx, [rsp+48]
int 80h
; add rsp, 8 ; bodge to remove ret addr from stack?
pop rdx
pop rcx
pop rbx
or rax, rax
js .errno
clc
ret
.errno:
neg rax
stc
ret
;
; takes system call number as arg
%macro system 1
mov rax, %1
call access.the.linux.kernel
%endmacro
; Macro's for calling syscalls
%macro sys.exit 0
system SYS_exit
%endmacro
%macro sys.fork 0
system SYS_fork
%endmacro
%macro sys.read 0
system SYS_read
%endmacro
%macro sys.write 0
system SYS_write
%endmacro
%macro output.char 1
push qword %1
call output_char
add rsp,8
%endmacro
%macro output.string 1
%%start:
push r9
push r8
push rdi
push rax
mov rdi, %1
mov rax, 0
call printf
pop rax
pop rdi
pop r8
pop r9
%endmacro
%macro output.minus 0 ; void output_minus()
push rax
mov rax, '-'
output.char rax
pop rax
%endmacro
%macro output.int 1
%endmacro
output_int:
push rbp
mov rbp, rsp
push rax
push rbx
push rdx
cmp qword [rbp+16], 0
jge L88
output.minus
neg qword [rbp+16]
L88:
mov rax, [rbp+16]
mov rdx, 0
mov rbx, 10
idiv rbx
cmp rax, 0
je L99
output.int rax
L99:
add rdx, '0'
output.char rdx
pop rdx
pop rbx
pop rax
mov rsp,rbp
pop rbp
ret
output_char:
push rax
push rbx
push rcx
push rdx
push r8 ; r8..r11 are altered by Linux kernel interrupt
push r9
push r10
push r11
push qword [octetbuffer] ; (just to make output_char() re-entrant...)
mov rax, SYS_write ; Linux system call 4; i.e. write ()
mov rbx, stdout ; File descriptor 1 i.e. standard output
; first argument
mov rcx, [rsp+80] ; fetch char from non-I/O-accessible segment
mov [octetbuffer], rcx ; load into 1-octet buffer
lea rcx, [octetbuffer] ; Address of 1-octet buffer
mov rdx, 1 ; Output 1 character only
int 80h ; Interrupt Linux kernel
pop qword [octetbuffer]
pop r11
pop r10
pop r9
pop r8
pop rdx
pop rcx
pop rbx
pop rax
ret
section .data
octetbuffer DQ 0