����8-3 linux/kernel/sys_call.s
1 /*
2 * linux/kernel/system_call.s
3 *
4 * (C) 1991 Linus Torvalds
5 */
6
7 /*
8 * system_call.s contains the system-call low-level handling routines.
9 * This also contains the timer-interrupt handler, as some of the code is
10 * the same. The hd- and flopppy-interrupts are also here.
11 *
12 * NOTE: This code handles signal-recognition, which happens every time
13 * after a timer-interrupt and after each system call. Ordinary interrupts
14 * don't handle signal-recognition, as that would clutter them up totally
15 * unnecessarily.
16 *
17 * Stack layout in 'ret_from_system_call':
18 *
19 * 0(%esp) - %eax
20 * 4(%esp) - %ebx
21 * 8(%esp) - %ecx
22 * C(%esp) - %edx
23 * 10(%esp) - original %eax (-1 if not system call)
24 * 14(%esp) - %fs
25 * 18(%esp) - %es
26 * 1C(%esp) - %ds
27 * 20(%esp) - %eip
28 * 24(%esp) - %cs
29 * 28(%esp) - %eflags
30 * 2C(%esp) - %oldesp
31 * 30(%esp) - %oldss
32 */
/*
* system_call.s�ļ�����ϵͳ���ã�system-call���ײ㴦���ӳ���������Щ����Ƚ����ƣ�
* ����ͬʱҲ����ʱ���жϴ�����timer-interrupt�������Ӳ�̺����̵��жϴ�������Ҳ�����
*
* ע�⣺��δ��봦���źţ�signal��ʶ����ÿ��ʱ���жϺ�ϵͳ����֮�����ʶ��һ��
* �жϹ��̲��������ź�ʶ����Ϊ���ϵͳ��ɻ��ҡ�
*
* ��ϵͳ���÷��أ�'ret_from_system_call'��ʱ��ջ�����ݼ�����19-30�С�
*/
# ����Linusԭע����һ���жϹ�����ָ����ϵͳ�����жϣ�int 0x80����ʱ���жϣ�int 0x20��
# ����������жϡ���Щ�жϻ����ں�̬���û�̬���������������Щ�жϹ�����Ҳ�����ź�ʶ��
# �Ļ������п�����ϵͳ�����жϺ�ʱ���жϹ����ж��źŵ�ʶ�����������ͻ����Υ�����ں�
# �������ռԭ�����ϵͳ���ޱ�Ҫ����Щ���������ж��д����źţ�Ҳ��������������
33
34 SIG_CHLD = 17 # ����SIG_CHLD�źţ��ӽ���ֹͣ���������
35
36 EAX = 0x00 # ��ջ�и����Ĵ�����ƫ��λ�á�
37 EBX = 0x04
38 ECX = 0x08
39 EDX = 0x0C
40 ORIG_EAX = 0x10 # �������ϵͳ���ã��������жϣ�ʱ����ֵΪ-1��
41 FS = 0x14
42 ES = 0x18
43 DS = 0x1C
44 EIP = 0x20 # 44 -- 48�� ��CPU�Զ���ջ��
45 CS = 0x24
46 EFLAGS = 0x28
47 OLDESP = 0x2C # ����Ȩ���仯ʱ��ԭ��ջָ��Ҳ����ջ��
48 OLDSS = 0x30
49
# ������Щ������ṹ��task_struct���б�����ƫ��ֵ���μ�include/linux/sched.h��105�п�ʼ��
50 state = 0 # these are offsets into the task-struct. # ����״̬�롣
51 counter = 4 # ��������ʱ�����(�ݼ�)���δ�����������ʱ��Ƭ��
52 priority = 8 # ����������������ʼ����ʱcounter=priority��Խ��������ʱ��Խ����
53 signal = 12 # ���ź�λͼ��ÿ������λ����һ���źţ��ź�ֵ=λƫ��ֵ+1��
54 sigaction = 16 # MUST be 16 (=len of sigaction) # sigaction�ṹ���ȱ�����16�ֽڡ�
55 blocked = (33*16) # �������ź�λͼ��ƫ������
56
# ���¶�����sigaction�ṹ�е�ƫ�������μ�include/signal.h����55�п�ʼ��
57 # offsets within sigaction
58 sa_handler = 0 # �źŴ������̵ľ��������������
59 sa_mask = 4 # �ź������롣
60 sa_flags = 8 # �źż���
61 sa_restorer = 12 # �ָ�����ָ�룬�μ�kernel/signal.c����˵����
62
63 nr_system_calls = 82 # Linux 0.12���ں��е�ϵͳ����������
64
65 ENOSYS = 38 # ϵͳ���úų����롣
66
67 /*
68 * Ok, I get parallel printer interrupts while using the floppy for some
69 * strange reason. Urgel. Now I just ignore them.
70 */
/*
* ���ˣ���ʹ������ʱ���յ��˲��д�ӡ���жϣ�����֡��ǣ����ڲ�������
*/
71 .globl _system_call,_sys_fork,_timer_interrupt,_sys_execve
72 .globl _hd_interrupt,_floppy_interrupt,_parallel_interrupt
73 .globl _device_not_available, _coprocessor_error
74
# ϵͳ���úŴ���ʱ�����س�����-ENOSYS��
75 .align 2 # �ڴ�4�ֽڶ��롣
76 bad_sys_call:
77 pushl $-ENOSYS # eax����-ENOSYS��
78 jmp ret_from_sys_call
# ����ִ�е��ȳ�����ڡ����ȳ���schedule()�ڣ�kernel/sched.c��119�д���ʼ��
# �����ȳ���schedule()����ʱ�ʹ�ret_from_sys_call����107�У�����ִ�С�
79 .align 2
80 reschedule:
81 pushl $ret_from_sys_call # ��ret_from_sys_call�ĵ�ַ��ջ��107�У���
82 jmp _schedule
#### int 0x80 --linuxϵͳ������ڵ㣨�����ж�int 0x80��eax���ǵ��úţ���
83 .align 2
84 _system_call:
85 push %ds # ����ԭ�μĴ���ֵ��
86 push %es
87 push %fs
88 pushl %eax # save the orig_eax # ����eaxԭֵ��
# һ��ϵͳ�������ɴ���3��������Ҳ���Բ���������������ջ��ebx��ecx��edx�з���ϵͳ
# ������ӦC���Ժ���������99�У��ĵ��ò������⼸���Ĵ�����ջ��˳������GNU gcc�涨�ģ�
# ebx�пɴ�ŵ�1��������ecx�д�ŵ�2��������edx�д�ŵ�3��������
# ϵͳ�������ɲμ�ͷ�ļ�include/unistd.h�е�150��200�е�ϵͳ���úꡣ
89 pushl %edx
90 pushl %ecx # push %ebx,%ecx,%edx as parameters
91 pushl %ebx # to the system call
# �ڱ�����μĴ���֮����ds,esָ���ں����ݶΣ���fsָ��ǰ�ֲ����ݶΣ���ָ��ִ�б�
# ��ϵͳ���õ��û���������ݶΡ�ע�⣬��Linux 0.12���ں˸��������Ĵ���������ڴ��
# ���ص��ģ����ǵĶλ�ַ�Ͷ�����ͬ���μ�fork.c������copy_mem()������
92 movl $0x10,%edx # set up ds,es to kernel space
93 mov %dx,%ds
94 mov %dx,%es
95 movl $0x17,%edx # fs points to local data space
96 mov %dx,%fs
97 cmpl _NR_syscalls,%eax # ���ú����������Χ�Ļ�����ת��
98 jae bad_sys_call
# �������������ĺ����ǣ����õ�ַ=[_sys_call_table + %eax * 4]���μ�������˵����
# sys_call_table[]��һ��ָ�����飬������include/linux/sys.h�У����������������ں�
# ����82��ϵͳ����C���������ĵ�ַ��
99 call _sys_call_table(,%eax,4) # ��ӵ���ָ������C������
100 pushl %eax # ��ϵͳ���÷���ֵ��ջ��
# ����101-106�в鿴��ǰ���������״̬��������ھ���״̬��state������0����ȥִ�е���
# ��������������ھ���״̬��������ʱ��Ƭ�Ѿ����꣨counter=0������Ҳȥִ�е��ȳ���
# ���統��̨�������еĽ���ִ�п����ն˶�д����ʱ����ôĬ�������¸ú�̨���������н���
# ���յ�SIGTTIN��SIGTTOU�źţ����½����������н��̴���ֹͣ״̬������ǰ�����������
# ���ء�
101 2:
102 movl _current,%eax # ȡ��ǰ�����̣����ݽṹָ����eax��
103 cmpl $0,state(%eax) # state
104 jne reschedule
105 cmpl $0,counter(%eax) # counter
106 je reschedule
# ������δ���ִ�д�ϵͳ����C�������غ��źŽ���ʶ�����������жϷ�������˳�ʱҲ
# ����ת��������д�������˳��жϹ��̣��������131���ϵĴ����������ж�int 16��
# �����б�ǰ�����Ƿ��dz�ʼ����task0��������ض�������ź�������Ĵ�����ֱ�ӷ��ء�
# 109���ϵ�_task��ӦC�����е�task[]���飬ֱ������task�൱������task[0]��
107 ret_from_sys_call:
108 movl _current,%eax
109 cmpl _task,%eax # task[0] cannot have signals
110 je 3f # ��ǰ(forward)��ת�����3���˳��жϴ�����
# ͨ����ԭ���ó������ѡ����ļ�����жϵ��ó����Ƿ����û��������������ֱ���˳��жϡ�
# ������Ϊ�������ں�ִ̬��ʱ������ռ���������������ź�����ʶ����������Ƚ�ѡ�����
# ��Ϊ�û�����ε�ѡ��� 0x000f��RPL=3���ֲ���������Σ����ж��Ƿ�Ϊ�û������������
# ��˵����ij���жϷ�����������ж�16����ת����107��ִ�е��ˣ�������ת�˳��жϳ���
# ���⣬���ԭ��ջ��ѡ�����Ϊ0x17����ԭ��ջ�����û����У���Ҳ˵������ϵͳ���õĵ�����
# �����û�������Ҳ�˳���
111 cmpw $0x0f,CS(%esp) # was old code segment supervisor ?
112 jne 3f
113 cmpw $0x17,OLDSS(%esp) # was stack segment = 0x17 ?
114 jne 3f
# ������δ��루115-128�����ڴ�����ǰ�����е��źš�����ȡ��ǰ����ṹ�е��ź�λͼ��32λ��
# ÿλ����1���źţ���Ȼ��������ṹ�е��ź����������Σ��룬�������������ź�λ��ȡ����ֵ
# ��С���ź�ֵ���ٰ�ԭ�ź�λͼ�и��źŶ�Ӧ��λ��λ����0��������ź�ֵ��Ϊ����֮һ��
# ��do_signal()��do_signal()�ڣ�kernel/signal.c,128���У����������13����ջ����Ϣ��
# ��do_signal()���źŴ�����������֮��������ֵ��Ϊ0���ٿ����Ƿ���Ҫ�л����̻��������
# �����źš�
115 movl signal(%eax),%ebx # ȡ�ź�λͼ��ebx��ÿ1λ����1���źţ���32���źš�
116 movl blocked(%eax),%ecx # ȡ���������Σ��ź�λͼ��ecx��
117 notl %ecx # ÿλȡ����
118 andl %ebx,%ecx # ������ɵ��ź�λͼ��
119 bsfl %ecx,%ecx # �ӵ�λ��λ0����ʼɨ��λͼ�����Ƿ���1��λ��
# ���У���ecx������λ��ƫ��ֵ�����ڼ�λ0--31����
120 je 3f # ���û���ź�����ǰ��ת�˳���
121 btrl %ecx,%ebx # ��λ���źţ�ebx����ԭsignalλͼ����
122 movl %ebx,signal(%eax) # ���±���signalλͼ��Ϣ��current->signal��
123 incl %ecx # ���źŵ���Ϊ��1��ʼ������1--32����
124 pushl %ecx # �ź�ֵ��ջ��Ϊ����do_signal�IJ���֮һ��
125 call _do_signal # ����C�����źŴ�������kernel/signal.c��128����
126 popl %ecx # ������ջ���ź�ֵ��
127 testl %eax, %eax # ���Է���ֵ������Ϊ0����ת��ǰ����2��101�У�����
128 jne 2b # see if we need to switch tasks, or do more signals
129 3: popl %eax # eax�к��е�100����ջ��ϵͳ���÷���ֵ��
130 popl %ebx
131 popl %ecx
132 popl %edx
133 addl $4, %esp # skip orig_eax # ������������ԭeaxֵ��
134 pop %fs
135 pop %es
136 pop %ds
137 iret
138
#### int16 -- �����������жϡ� ���ͣ����������롣
# ����һ���ⲿ�Ļ���Ӳ�����쳣����Э���������Լ���������ʱ���ͻ�ͨ��ERROR����
# ֪ͨCPU������������ڴ���Э�����������ij����źš�����תȥִ��C����math_error()
# ��kernel/math/error.c 11�������غ���ת�����ret_from_sys_call������ִ�С�
139 .align 2
140 _coprocessor_error:
141 push %ds
142 push %es
143 push %fs
144 pushl $-1 # fill in -1 for orig_eax # ��-1����������ϵͳ���á�
145 pushl %edx
146 pushl %ecx
147 pushl %ebx
148 pushl %eax
149 movl $0x10,%eax # ds,es��Ϊָ���ں����ݶΡ�
150 mov %ax,%ds
151 mov %ax,%es
152 movl $0x17,%eax # fs��Ϊָ��ֲ����ݶΣ�������������ݶΣ���
153 mov %ax,%fs
154 pushl $ret_from_sys_call # ��������÷��صĵ�ַ��ջ��
155 jmp _math_error # ִ��math_error()��kernel/math/error.c��11����
156
#### int7 -- �豸�����ڻ�Э�����������ڡ� ���ͣ����������롣
# ������ƼĴ��� CR0 ��EM��ģ�⣩��־��λ����CPU ִ��һ��Э������ָ��ʱ�ͻ�������
# �жϣ�����CPU�Ϳ����л���������жϴ�������ģ��Э������ָ�181�У���
# CR0�Ľ�����־TS���� CPUִ������ת��ʱ���õġ�TS ��������ȷ��ʲôʱ��Э�������е�
# ������CPU ����ִ�е�����ƥ���ˡ���CPU ������һ��Э������ת��ָ��ʱ����TS��λʱ��
# �ͻ��������жϡ���ʱ�Ϳ��Ա���ǰһ�������Э���������ݣ����ָ��������Э������ִ��
# ״̬��176�У����μ�kernel/sched.c��92�С����ж����ת�Ƶ����ret_from_sys_call
# ��ִ����ȥ����Ⲣ�����źţ���
157 .align 2
158 _device_not_available:
159 push %ds
160 push %es
161 push %fs
162 pushl $-1 # fill in -1 for orig_eax # ��-1����������ϵͳ���á�
163 pushl %edx
164 pushl %ecx
165 pushl %ebx
166 pushl %eax
167 movl $0x10,%eax # ds,es��Ϊָ���ں����ݶΡ�
168 mov %ax,%ds
169 mov %ax,%es
170 movl $0x17,%eax # fs��Ϊָ��ֲ����ݶΣ�������������ݶΣ���
171 mov %ax,%fs
# ��CR0�������ѽ�����־TS����ȡCR0ֵ��������Э�����������־EMû����λ��˵������
# EM������жϣ���ָ�����Э������״̬��ִ��C���� math_state_restore()�����ڷ���ʱ
# ȥִ��ret_from_sys_call���Ĵ��롣
172 pushl $ret_from_sys_call # ��������ת����õķ��ص�ַ��ջ��
173 clts # clear TS so that we can use math
174 movl %cr0,%eax
175 testl $0x4,%eax # EM (math emulation bit)
176 je _math_state_restore # ִ��math_state_restore()��kernel/sched.c��92�У���
# ��EM��־��λ����ȥִ����ѧ�������math_emulate()��
177 pushl %ebp
178 pushl %esi
179 pushl %edi
180 pushl $0 # temporary storage for ORIG_EIP
181 call _math_emulate # ����C������math/math_emulate.c��476����
182 addl $4,%esp # ������ʱ�洢��
183 popl %edi
184 popl %esi
185 popl %ebp
186 ret # �����ret����ת��ret_from_sys_call(107��)��
187
#### int32 -- (int 0x20) ʱ���жϴ��������ж�Ƶ������Ϊ100Hz(include/linux/sched.h,4)��
# ��ʱоƬ8253/8254����(kernel/sched.c,438)����ʼ���ġ��������jiffiesÿ10�����1��
# ��δ��뽫jiffies��1�����ͽ����ж�ָ���8259��������Ȼ���õ�ǰ��Ȩ����Ϊ��������
# C����do_timer(long CPL)�������÷���ʱתȥ��Ⲣ�����źš�
188 .align 2
189 _timer_interrupt:
190 push %ds # save ds,es and put kernel data space
191 push %es # into them. %fs is used by _system_call
192 push %fs # ����ds��es������ָ���ں����ݶΡ�fs������system_call��
193 pushl $-1 # fill in -1 for orig_eax # ��-1����������ϵͳ���á�
# �������DZ���Ĵ���eax��ecx��edx��������Ϊgcc�������ڵ��ú���ʱ���ᱣ�����ǡ�����Ҳ
# ������ebx�Ĵ�������Ϊ�ں���ret_from_sys_call�л��õ�����
194 pushl %edx # we save %eax,%ecx,%edx as gcc doesn't
195 pushl %ecx # save those across function calls. %ebx
196 pushl %ebx # is saved as we use that in ret_sys_call
197 pushl %eax
198 movl $0x10,%eax # ds,es��Ϊָ���ں����ݶΡ�
199 mov %ax,%ds
200 mov %ax,%es
201 movl $0x17,%eax # fs��Ϊָ��ֲ����ݶΣ���������ݶΣ���
202 mov %ax,%fs
203 incl _jiffies
# ���ڳ�ʼ���жϿ���оƬʱû�в����Զ�EOI������������Ҫ��ָ�������Ӳ���жϡ�
204 movb $0x20,%al # EOI to interrupt controller #1
205 outb %al,$0x20
# ����Ӷ�ջ��ȡ��ִ��ϵͳ���ô����ѡ�����CS�μĴ���ֵ���еĵ�ǰ��Ȩ����(0��3)��ѹ��
# ��ջ����Ϊdo_timer�IJ�����do_timer()����ִ�������л�����ʱ�ȹ�������kernel/sched.c��
# 324��ʵ�֡�
206 movl CS(%esp),%eax
207 andl $3,%eax # %eax is CPL (0 or 3, 0=supervisor)
208 pushl %eax
209 call _do_timer # 'do_timer(long CPL)' does everything from
210 addl $4,%esp # task switching to accounting ...
211 jmp ret_from_sys_call
212
#### ����sys_execve()ϵͳ���á�ȡ�жϵ��ó���Ĵ���ָ����Ϊ��������C����do_execve()��
# do_execve()��fs/exec.c��207��
213 .align 2
214 _sys_execve:
215 lea EIP(%esp),%eax # eaxָ���ջ�б����û�����eipָ�봦��
216 pushl %eax
217 call _do_execve
218 addl $4,%esp # ��������ʱѹ��ջ��EIPֵ��
219 ret
220
#### sys_fork()���ã����ڴ����ӽ��̣���system_call����2��ԭ����include/linux/sys.h�С�
# ���ȵ���C����find_empty_process()��ȡ��һ�����̺�last_pid�������ظ�����˵��Ŀǰ����
# ����������Ȼ�����copy_process()���ƽ��̡�
221 .align 2
222 _sys_fork:
223 call _find_empty_process # Ϊ�½���ȡ�ý��̺�last_pid����kernel/fork.c��143����
224 testl %eax,%eax # ��eax�з��ؽ��̺š������ظ������˳���
225 js 1f
226 push %gs
227 pushl %esi
228 pushl %edi
229 pushl %ebp
230 pushl %eax
231 call _copy_process # ����C����copy_process()��kernel/fork.c��68����
232 addl $20,%esp # ������������ѹջ���ݡ�
233 1: ret
234
#### int 46 -- (int 0x2E) Ӳ���жϴ���������ӦӲ���ж�����IRQ14��
# �������Ӳ�̲�����ɻ�����ͻᷢ�����ж��źš�(�μ�kernel/blk_drv/hd.c)��
# ������8259A�жϿ��ƴ�оƬ���ͽ���Ӳ���ж�ָ��(EOI)��Ȼ��ȡ����do_hd�еĺ���ָ�����edx
# �Ĵ����У�����do_hdΪNULL�������ж�edx����ָ���Ƿ�Ϊ�ա����Ϊ�գ����edx��ֵָ��
# unexpected_hd_interrupt()��������ʾ������Ϣ�������8259A��оƬ��EOIָ�������edx��
# ָ��ָ��ĺ���: read_intr()��write_intr()��unexpected_hd_interrupt()��
235 _hd_interrupt:
236 pushl %eax
237 pushl %ecx
238 pushl %edx
239 push %ds
240 push %es
241 push %fs
242 movl $0x10,%eax # ds,es��Ϊ�ں����ݶΡ�
243 mov %ax,%ds
244 mov %ax,%es
245 movl $0x17,%eax # fs��Ϊ���ó���ľֲ����ݶΡ�
246 mov %ax,%fs
# ���ڳ�ʼ���жϿ���оƬʱû�в����Զ�EOI������������Ҫ��ָ�������Ӳ���жϡ�
247 movb $0x20,%al
248 outb %al,$0xA0 # EOI to interrupt controller #1 # �ʹ�8259A��
249 jmp 1f # give port chance to breathe # ����jmp����ʱ���á�
250 1: jmp 1f
# do_hd����Ϊһ������ָ�룬������ֵread_intr()��write_intr()������ַ���ŵ�edx�Ĵ�����
# �ͽ�do_hdָ�������ΪNULL��Ȼ����Եõ��ĺ���ָ�룬����ָ��Ϊ�գ������ָ��ָ��C
# ����unexpected_hd_interrupt()���Դ���δ֪Ӳ���жϡ�
251 1: xorl %edx,%edx
252 movl %edx,_hd_timeout # hd_timeout��Ϊ0����ʾ���������ڹ涨ʱ���ڲ������жϡ�
253 xchgl _do_hd,%edx
254 testl %edx,%edx
255 jne 1f # ���գ�����ָ��ָ��C����unexpected_hd_interrupt()��
256 movl $_unexpected_hd_interrupt,%edx
257 1: outb %al,$0x20 # ��8259A��оƬEOIָ�����Ӳ���жϣ���
258 call *%edx # "interesting" way of handling intr.
259 pop %fs # �Ͼ����do_hdָ���C������
260 pop %es
261 pop %ds
262 popl %edx
263 popl %ecx
264 popl %eax
265 iret
266
#### int38 -- (int 0x26) �����������жϴ���������ӦӲ���ж�����IRQ6��
# �䴦�������������Ӳ�̵Ĵ�������һ������kernel/blk_drv/floppy.c����
# ������8259A�жϿ�������оƬ����EOIָ�Ȼ��ȡ����do_floppy�еĺ���ָ�����eax
# �Ĵ����У�����do_floppyΪNULL�������ж�eax����ָ���Ƿ�Ϊ�ա���Ϊ�գ����eax��ֵָ��
# unexpected_floppy_interrupt ()��������ʾ������Ϣ��������eaxָ��ĺ���: rw_interrupt,
# seek_interrupt,recal_interrupt,reset_interrupt��unexpected_floppy_interrupt��
267 _floppy_interrupt:
268 pushl %eax
269 pushl %ecx
270 pushl %edx
271 push %ds
272 push %es
273 push %fs
274 movl $0x10,%eax # ds,es��Ϊ�ں����ݶΡ�
275 mov %ax,%ds
276 mov %ax,%es
277 movl $0x17,%eax # fs��Ϊ���ó���ľֲ����ݶΡ�
278 mov %ax,%fs
279 movb $0x20,%al # ����8259A�жϿ�����EOIָ�����Ӳ���жϣ���
280 outb %al,$0x20 # EOI to interrupt controller #1
# do_floppyΪһ����ָ�룬������ֵʵ�ʴ���C����ָ�롣��ָ���ڱ������ŵ�eax�Ĵ�����ͽ�
# do_floppy�����ÿա�Ȼ�����eax��ԭָ���Ƿ�Ϊ�գ�������ʹָ��ָ��C����
# unexpected_floppy_interrupt()��
281 xorl %eax,%eax
282 xchgl _do_floppy,%eax
283 testl %eax,%eax # ���Ժ���ָ���Ƿ�=NULL?
284 jne 1f # ���գ���ʹָ��ָ��C����unexpected_floppy_interrupt()��
285 movl $_unexpected_floppy_interrupt,%eax
286 1: call *%eax # "interesting" way of handling intr. # ��ӵ��á�
287 pop %fs # �Ͼ����do_floppyָ��ĺ�����
288 pop %es
289 pop %ds
290 popl %edx
291 popl %ecx
292 popl %eax
293 iret
294
#### int 39 -- (int 0x27) ���п��жϴ�������ӦӲ���ж������ź�IRQ7��
# ���汾�ں˻�δʵ�֡�����ֻ�Ƿ���EOIָ�
295 _parallel_interrupt:
296 pushl %eax
297 movb $0x20,%al
298 outb %al,$0x20
299 popl %eax
300 iret