-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstud_io.inc
169 lines (152 loc) · 3.33 KB
/
stud_io.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
;; File stud_io.inc for both Linux and FreeBSD.
;;
;; Copyright (c) Andrey Vikt. Stolyarov, 2009, 2015, 2017
;;
;; I, the author, hereby grant everyone the right to use this file for any
;; purpose, in any manner, in it's original or modified form, provided that
;; modified versions are clearly marked as such AND the original author's
;; copyright notice is kept along with the other authors' copyright notices
;; as appropriate within the file.
;;
;; Only the file as such must retain the copyright notice. Programs created
;; using this file (e.g. binaries) don't need to have any mentions of the fact
;; this file was used to create them.
;;
;; This file is provided as is, with absolutely NO WARRANTY, and this
;; statement must be taken literally: "NO" means "NO", period. Should
;; this needs additional clarifications, I'd like you to search Internet
;; for various types of warranty (e.g., implied, hidden, etc) and take
;; into account that you don't have them all.
;;
%define STUD_IO_LINUX
;%define STUD_IO_FREEBSD
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; system dependend part
%ifdef STUD_IO_LINUX
; generic 3-param syscall
%macro _syscall_3 4
push edx
push ecx
push ebx ; it is senseless to save eax as it holds the return
push %1
push %2
push %3
push %4
pop edx
pop ecx
pop ebx
pop eax
int 0x80
pop ebx
pop ecx
pop edx
%endmacro
; syscall_exit is the only syscall we use that has 1 parameter
%macro _syscall_exit 1
mov ebx, %1 ; exit code
mov eax, 1 ; 1 = sys_exit
int 0x80
%endmacro
%elifdef STUD_IO_FREEBSD
; generic 3-param syscall
%macro _syscall_3 4
push %4
push %3
push %2
mov eax, %1
push eax
int 0x80
add esp, 16
%endmacro
%macro _syscall_exit 1
push %1 ; exit code
mov eax, 1 ; 1 = sys_exit
push eax
int 0x80
; no cleanup - this will never return anyway
%endmacro
%else
%error You must define either STUD_IO_LINUX or STUD_IO_FREEBSD
%endif
;; system dependent part ends here
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; %1: descriptor %2: buffer addr %3: buffer length
; output: eax: read bytes
%macro _syscall_read 3
_syscall_3 3,%1,%2,%3
%endmacro
; %1: descriptor %2: buffer addr %3: buffer length
; output: eax: written bytes
%macro _syscall_write 3
_syscall_3 4,%1,%2,%3
%endmacro
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
%macro PRINT 1
pusha
pushf
jmp %%astr
%%str db %1
%%strln equ $-%%str
%%astr: _syscall_write 1, %%str, %%strln
popf
popa
%endmacro
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
%macro PUTCHAR 1
pusha
pushf
%ifstr %1
mov al, %1
%elifnum %1
mov al, %1
%elifidni %1,al
nop
%elifidni %1,ah
mov al, ah
%elifidni %1,bl
mov al, bl
%elifidni %1,bh
mov al, bh
%elifidni %1,cl
mov al, cl
%elifidni %1,ch
mov al, ch
%elifidni %1,dl
mov al, dl
%elifidni %1,dh
mov al, dh
%else
mov al, %1 ; let's hope it is a memory location such as [var]
%endif
sub esp, 4 ; reserve memory for buffer
mov edi, esp
mov [edi], al
_syscall_write 1, edi, 1
add esp, 4
popf
popa
%endmacro
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
%macro GETCHAR 0
pushf
push edi
sub esp, 4
mov edi, esp
_syscall_read 0, edi, 1
cmp eax, 1
jne %%eof_reached
xor eax, eax
mov al, [edi]
jmp %%gcquit
%%eof_reached:
xor eax, eax
not eax ; eax := -1
%%gcquit:
add esp, 4
pop edi
popf
%endmacro
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
%macro FINISH 0-1 0
_syscall_exit %1
%endmacro