-
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathnaskfunc.s
322 lines (283 loc) · 5.31 KB
/
naskfunc.s
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
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
.equ CONSOLE, 0x0fec # コンソール構造体のアドレス
.equ OS_ESP, 0xfe4 # OS用のESP
.code32
.extern inthandler21, inthandler21, inthander27, inthandler2c
.extern cons_putchar
.extern hrb_api
.global io_hlt, io_cli, io_sti, io_stihlt
.global io_in8, io_in16, io_in32
.global io_out8, io_out16, io_out32
.global io_load_eflags, io_store_eflags
.global load_gdtr, load_idtr
.global load_cr0, store_cr0
.global load_tr
.global asm_inthandler0c, asm_inthandler0d
.global asm_inthandler20, asm_inthandler21, asm_inthandler27, asm_inthandler2c
.global asm_cons_putchar
.global asm_hrb_api
.global start_app
.global asm_end_app
.global memtest_sub
.global farjmp
.global farcall
.text
io_hlt: # void io_hlt(void)
hlt
ret
io_cli: # void io_cli(void)
cli
ret
io_sti: # void io_sti(void)
sti
ret
io_stihlt: # void io_stihlt(void)
sti
hlt
ret
io_in8: # int io_in8(int port)
movl 4(%esp), %edx
movl $0, %eax
inb %dx, %al
ret
io_in16: # int io_in16(int port)
movl 4(%esp), %edx
movl $0, %eax
inw %dx, %ax
ret
io_in32: # int io_in32(int port)
movl 4(%esp), %edx
movl $0, %eax
inl %dx, %eax
ret
io_out8: # int io_out8(int port, int data)
movl 4(%esp), %edx
movb 8(%esp), %al
outb %al, %dx
ret
io_out16: # int io_out16(int port, int data)
movl 4(%esp), %edx
movl 8(%esp), %eax
outw %ax, %dx
ret
io_out32: # int io_out32(int port, int data)
movl 4(%esp), %edx
movl 8(%esp), %eax
outl %eax, %dx
ret
io_load_eflags: # int io_load_eflags(void)
pushf # push eflags
pop %eax
ret
io_store_eflags: # void io_store_eflags(int eflags)
movl 4(%esp), %eax
push %eax
popf # pop eflags
ret
load_gdtr: # void load_gdtr(int limit, int addr)
movw 4(%esp), %ax # limit
movw %ax, 6(%esp)
lgdt 6(%esp)
ret
load_idtr: # void load_idtr(int limit, int addr)
movw 4(%esp), %ax # limit
movw %ax, 6(%esp)
lidt 6(%esp)
ret
load_cr0: # int load_cr0()
movl %cr0, %eax
ret
store_cr0: # void store_cr0(int cr0)
movl 4(%esp), %eax
movl %eax, %cr0
ret
load_tr: # void load_tr(int tr)
ltr 4(%esp)
ret
asm_inthandler0c:
sti
pushw %es
pushw %ds
pusha
movl %esp, %eax
pushl %eax
movw %ss, %ax
movw %ax, %ds
movw %ax, %es
call inthandler0c
cmpl $0, %eax
jne asm_end_app
popl %eax
popa
popw %ds
popw %es
add $4, %esp
iret
asm_inthandler0d:
sti
pushw %es
pushw %ds
pusha
movl %esp, %eax
pushl %eax
movw %ss, %ax
movw %ax, %ds
movw %ax, %es
call inthandler0d
cmpl $0, %eax
jne asm_end_app
popl %eax
popa
popw %ds
popw %es
add $4, %esp
iret
asm_inthandler20:
pushw %es
pushw %ds
pusha
movl %esp, %eax
pushl %eax
movw %ss, %ax
movw %ax, %ds
movw %ax, %es
call inthandler20
popl %eax
popa
popw %ds
popw %es
iret
asm_inthandler21:
pushw %es
pushw %ds
pusha
movl %esp, %eax
pushl %eax
movw %ss, %ax
movw %ax, %ds
movw %ax, %es
call inthandler21
popl %eax
popa
popw %ds
popw %es
iret
asm_inthandler27:
pushw %es
pushw %ds
pusha
movl %esp, %eax
pushl %eax
movw %ss, %ax
movw %ax, %ds
movw %ax, %es
call inthandler27
popl %eax
popa
popw %ds
popw %es
iret
asm_inthandler2c:
pushw %es
pushw %ds
pusha
movl %esp, %eax
pushl %eax
movw %ss, %ax
movw %ax, %ds
movw %ax, %es
call inthandler2c
popl %eax
popa
popw %ds
popw %es
iret
asm_cons_putchar:
sti
push $1
andl $0xff, %eax
pushl %eax
pushl (CONSOLE)
call cons_putchar
addl $12, %esp
iret
asm_hrb_api:
sti
pushw %ds
pushw %es
pusha # 保存のためpush
pusha # hrb_apiに渡すためpush
movw %ss, %ax
movw %ax, %ds
movw %ax, %es
call hrb_api
cmpl $0, %eax # EAXが0でなければアプリ異常処理
jne asm_end_app
addl $32, %esp
popa
popw %es
popw %ds
iret
asm_end_app:
movl (%eax), %esp # eaxはtss.esp0の番地
movl $0, 4(%eax)
popa
ret # cmd_appへ帰る
start_app: # void start_app(int eip, int cs, int esp, int ds, int *tss_esp0)
pusha # 32ビット・レジスタを全部保存しておく
movl 36(%esp), %eax # アプリ用のEIP
movl 40(%esp), %ecx # アプリ用のCS
movl 44(%esp), %edx # アプリ用のESP
movl 48(%esp), %ebx # アプリ用のDS/SS
movl 52(%esp), %ebp # tss.esp0の番地
movl %esp, (%ebp) # OS用のESPを保存
movw %ss, 4(%ebp) # OS用のSSを保存
movw %bx, %es
movw %bx, %ds
movw %bx, %fs
movw %bx, %gs
# 以下は、lretでアプリに行かせるためのスタック調整
orl $3, %ecx
orl $3, %ebx
pushl %ebx
pushl %edx
pushl %ecx
pushl %eax
lret
memtest_sub: # unsigned int memtest_sub(unsigned int start, unsigned int end)
pushl %edi
pushl %esi
pushl %ebx
movl $0xaa55aa55, %esi # pat0 = 0xaa55aa55
movl $0x55aa55aa, %edi # pat1 = 0x55aa55aa
movl 16(%esp), %eax # i = start
mts_loop:
movl %eax, %ebx
addl $0xffc, %ebx # p = i + 0xffc
movl (%ebx), %edx # old = *p
movl %esi, (%ebx) # *p = pat0
xorl $0xffffffff, (%ebx) # *p ^= 0xffffffff
cmpl (%ebx), %edi # if (*p != pat1) goto mts_fin
jne mts_fin
xorl $0xffffffff, (%ebx) # *p ^= 0xffffffff
cmpl (%ebx), %esi # if (*p != pat0) goto mts_fin
jne mts_fin
movl %edx, (%ebx) # *p = old
addl $0x1000, %eax # i += 0x1000
cmpl 20(%esp), %eax # if (i <= end) goto mts_loop
jbe mts_loop
popl %ebx
popl %esi
popl %edi
ret
mts_fin:
movl %edx, (%ebx) # *p = old
popl %ebx
popl %esi
popl %edi
ret
farjmp: # void farjmp(int eip, int cs)
ljmpl *4(%esp)
ret
farcall: # void farcall(int eip, int cs)
lcall *4(%esp)
ret