forked from VictorYXL/MyOS
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathnasmfunc.nsm
211 lines (172 loc) · 3.58 KB
/
nasmfunc.nsm
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
; naskfunc
; TAB=4
;[FORMAT "WCOFF"] ; nasm -f coff
[BITS 32] ;
GLOBAL _io_hlt,_write_mem8,_io_cli,_io_sti,_io_stihlt
GLOBAL _io_in8,_io_in16,_io_in32,_io_out8,_io_out16,_io_out32
GLOBAL _io_load_eflags,_io_store_eflags
GLOBAL _load_gdtr,_load_idtr,_load_tr
GLOBAL _nsm_inthandler20,_nsm_inthandler21,_nsm_inthandler27,_nsm_inthandler2c
GLOBAL _load_cr0,_store_cr0
GLOBAL _farjmp,_shutdown
EXTERN _inthandler20,_inthandler21,_inthandler27,_inthandler2c
[SECTION .text] ;
_io_hlt: ;void io_hlt(void)
HLT ;使操作系统交出CPU控制权
RET
_write_mem8: ;void write_mem8(int addr,int data) 向指定地址写入int,参数传递使用栈的方式,ESP为栈顶指针
MOV ECX,[ESP+4] ;第n个参数的地址为ESP+n*4(4是由于我们采用32位模式,一次输入4字节)
MOV AL,[ESP+8]
MOV [ECX],AL
RET
_io_cli: ;void io_cli(void)
CLI ;不允许中断
RET
_io_sti: ;void io_cli(void)
STI ;允许中断
RET
_io_stihlt: ;void io_cli(void)
STI
HLT
RET
_io_in8: ;int io_in8(int port)
MOV EDX,[ESP+4]
MOV EAX,0
IN AL,DX ;IN 读取设备对应端口的电气信息 IN AL/AX/EAX port
RET
_io_in16: ;int io_in16(int port)
MOV EDX,[ESP+4]
MOV EAX,0
IN AX,DX
RET
_io_in32: ;int io_in32(int port)
MOV EDX,[ESP+4]
MOV EAX,0
IN EAX,DX
RET
_io_out8: ;int io_out8(int port,int data)
MOV EDX,[ESP+4]
MOV AL,[ESP+8]
OUT DX,AL ;OUT 向设备对应端口写入电气信息 OUT port AL/AX/EAX
RET
_io_out16: ;int io_out16(int port,int data)
MOV EDX,[ESP+4]
MOV AX,[ESP+8]
OUT DX,AX
RET
_io_out32: ;int io_out32(int port,int data)
MOV EDX,[ESP+4]
MOV EAX,[ESP+8]
OUT DX,EAX
RET
_io_load_eflags: ;int io_load_eflags(void)
PUSHFD ;按dword格式push eflags
POP EAX
RET
_io_store_eflags: ;int io_store_eflags(int eflags)
MOV EAX,[ESP+4]
PUSH EAX
POPFD ;按dword格式pop eflags
RET
;GDTR有6个字节,后两个字节表示段上限,前四个字节为段表开始地址
_load_gdtr: ;void load_gdtr(int limit,int addr)
MOV AX,[ESP+4]
MOV [ESP+6],AX
LGDT [ESP+6]
RET
_load_idtr: ;void load_idtr(int limit,int addr)
MOV AX,[ESP+4]
MOV [ESP+6],AX
LIDT [ESP+6]
RET
;修改tr,tr记录当前正在执行的任务
_load_tr:
LTR [ESP+4]
RET
_nsm_inthandler20:
;保护现场
PUSH ES
PUSH DS
PUSHAD ;PUSH EAX,ECX,EDX,EBX,ESP,EBP,ESI,EDI
;中断处理
MOV EAX,ESP ;汇编中调用C程序,将参数依次压入栈中(左边的在栈底)
PUSH EAX
MOV AX,SS
MOV DS,AX
MOV ES,AX
CALL _inthandler20
POP EAX
;恢复现场
POPAD
POP DS
POP ES
IRETD
_nsm_inthandler21:
;保护现场
PUSH ES
PUSH DS
PUSHAD ;PUSH EAX,ECX,EDX,EBX,ESP,EBP,ESI,EDI
;中断处理
MOV EAX,ESP ;汇编中调用C程序,将参数依次压入栈中(左边的在栈底)
PUSH EAX
MOV AX,SS
MOV DS,AX
MOV ES,AX
CALL _inthandler21
POP EAX
;恢复现场
POPAD
POP DS
POP ES
IRETD
_nsm_inthandler27:
;保护现场
PUSH ES
PUSH DS
PUSHAD ;PUSH EAX,ECX,EDX,EBX,ESP,EBP,ESI,EDI
;中断处理
MOV EAX,ESP ;汇编中调用C程序,将参数依次压入栈中(左边的在栈底)
PUSH EAX
MOV AX,SS
MOV DS,AX
MOV ES,AX
CALL _inthandler27
POP EAX
;恢复现场
POPAD
POP DS
POP ES
IRETD
_nsm_inthandler2c:
;保护现场
PUSH ES
PUSH DS
PUSHAD ;PUSH EAX,ECX,EDX,EBX,ESP,EBP,ESI,EDI
;中断处理
MOV EAX,ESP ;汇编中调用C程序,将参数依次压入栈中(左边的在栈底)
PUSH EAX
MOV AX,SS
MOV DS,AX
MOV ES,AX
CALL _inthandler2c
POP EAX
;恢复现场
POPAD
POP DS
POP ES
IRETD
_load_cr0: ;int load_cr0(void)
MOV EAX,CR0;
RET
_store_cr0: ;store_cr0(int cr0)
MOV EAX,[ESP+4]
MOV CR0,EAX
RET
;切换任务,一般的跳转为near模式,不改变CS;far模式跳转改变CS,切换任务
_farjmp: ;连续读取6个字节前4个写入EIP寄存器,后两个写入CS寄存器
JMP FAR[ESP+4]
RET
_shutdown:
MOV AX,5301H
XOR BX,BX
INT 15H