����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