⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 2.html

📁 介绍linux下文件和设备编程
💻 HTML
📖 第 1 页 / 共 5 页
字号:
&nbsp;&nbsp; |SAVE_ALL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ---<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |do_IRQ&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp; wrapper routines<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |handle_IRQ_event&nbsp; ---<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |handler() -&gt; timer_interrupt&nbsp; // registered IRQ 0 handler<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |do_timer_interrupt<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |do_timer<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |jiffies++;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |update_process_times<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |if (--counter &lt;= 0) { // if time slice ended then<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |counter = 0;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;&nbsp; reset counter<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |need_resched = 1;&nbsp;&nbsp; //&nbsp;&nbsp; prepare to reschedule<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |do_softirq<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |while (need_resched) { // if necessary<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |schedule&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;&nbsp; reschedule<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |handle_softirq<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |}<br>&nbsp;&nbsp; |RESTORE_ALL<p>&middot;IRQ0x00_interrupt, SAVE_ALL [include/asm/hw_irq.h]<br>&middot;do_IRQ, handle_IRQ_event [arch/i386/kernel/irq.c]<br>&middot;timer_interrupt, do_timer_interrupt [arch/i386/kernel/time.c]<br>&middot;do_timer, update_process_times [kernel/timer.c]<br>&middot;do_softirq [kernel/soft_irq.c]<br>&middot;RESTORE_ALL, while loop [arch/i386/kernel/entry.S]<p>&nbsp;&nbsp;&nbsp; 系统启动核心时,调用start_kernal()继续各方面的初始化,在这之前,各种中断都被禁止,只有在完成必要的初始化后,直到执行完Kmalloc_init()后,才允许中断(init\main.c)。与时钟中断有关的部分初始化如下:<p>&nbsp;&nbsp;&nbsp; 调用trap_init()设置各种trap入口,如system_call、GDT entry、LDT entry、call gate等。其中0~17为各种错误入口,18~47保留。<p>&nbsp;&nbsp;&nbsp; 调用init_IRQ()函数设置核心系统的时钟周期为10ms,即100HZ,它是以后按照轮转法进行CPU调度时所依照的基准时钟周期。每10ms产生的时钟中断信号直接输入到第一块8259A的INT 0(即irq0)。初始化中断矢量表中从0x20起的17个中断矢量,用bad_IRQ#_interrupt函数的地址(#为中断号)填写。<p>&nbsp;&nbsp;&nbsp; 调用sched_init()函数,设置启动第一个进程init_task。设置用于管理bottom_half机制的数据结构bh_base[],规定三类事件的中断处理函数,即时钟TIMER_BH、设备TQUEUE_BH和IMMEDIATE_BH。<p>&nbsp;&nbsp;&nbsp; 调用time_init()函数,首先读取当时的CMOS时间,最后调用setup_x86_irq(0,&amp;irq0)函数,把irq0挂到irq_action[0]队列的后面,并把中断矢量表中第0x20项,即timer中断对应的中断矢量改为IRQ0_interrupt函数的地址,在irq0中,指定时间中断服务程序是timer_interrupt,<br>&nbsp;&nbsp;&nbsp;&nbsp; static struct irqaction irq0&nbsp; = { timer_interrupt, 0, 0, &quot;timer&quot;, NULL, NULL}<br>&nbsp;&nbsp;&nbsp; 结构irqaction的定义如下:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct irqaction {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; void (*handler)(int, void *, struct pt_regs *);&nbsp; /* 中断服务函数入口 */<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; unsigned long flags;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* 服务允中与否标记 */<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned long mask;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; const char *name;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; void *dev_id;<br>&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct irqaction *next;<br>&nbsp;&nbsp;&nbsp; };<br>&nbsp;&nbsp;&nbsp; 其中,若flag==SA_INTERRUPT,则中断矢量改为fast_IRQ#_interrupt,在执行中断服务的过程中不允许出现中断,若为其它标记,则中断矢量为IRQ#_interrupt,在执行中断服务的过程中,允许出现中断。<br>Irq_action的定义与初始化如下:<br>&nbsp;&nbsp;&nbsp; static void (*interrupt[17])(void) = {IRQ#_interrupt};<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; static void (*fast_interrupt[16])(void) = {fast_IRQ#_interrupt};<br>&nbsp;&nbsp;&nbsp; static void (*bad_interrupt[16])(void) = {bad_IRQ#_interrupt};(以上#为中断号)<br>&nbsp;&nbsp;&nbsp; static struct irqaction *irq_action[16] = {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; NULL, NULL, NULL, NULL,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; NULL, NULL, NULL, NULL,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; NULL, NULL, NULL, NULL,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; NULL, NULL, NULL, NULL<br>&nbsp;&nbsp;&nbsp; };<p>&nbsp;&nbsp;&nbsp; irq_action是一个全局数组,每个元素指向一个irq队列,共16个irq队列,时钟中断请求队列在第一个队列,即irq_action[0]。当每个中断请求到来时,都调用setup_x86_irq把该请求挂到相应的队列的后面。<p>&nbsp;&nbsp;&nbsp; 以后,系统每10ms产生一次时钟中断信号,该信号直接输入到第一块8259A的INT 0(即irq0)。CPU根据中断矢量表和中断源,找到中断矢量函数入口IRQ0_interrupt(程序运行过程中允许中断)或者fast_IRQ0_interrupt(程序运行过程中不允许中断)或者bad_IRQ0_interrupt(不执行任何动作,直接返回),这些函数由宏BUILD_TIMER_IRQ(chip, nr, mask)展开定义。<br>宏BUILD_TIMER_IRQ(chip, nr, mask)的定义如下:<br>#define BUILD_TIMER_IRQ(chip,nr,mask) \<br>asmlinkage void IRQ_NAME(nr); \<br>asmlinkage void FAST_IRQ_NAME(nr); \<br>asmlinkage void BAD_IRQ_NAME(nr); \<br>__asm__( \<br>&quot;\n&quot;__ALIGN_STR&quot;\n&quot; \<br>SYMBOL_NAME_STR(fast_IRQ) #nr &quot;_interrupt:\n\t&quot; \<br>SYMBOL_NAME_STR(bad_IRQ) #nr &quot;_interrupt:\n\t&quot; \<br>SYMBOL_NAME_STR(IRQ) #nr &quot;_interrupt:\n\t&quot; \<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &quot;pushl $-&quot;#nr&quot;-2\n\t&quot; \<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SAVE_ALL \<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ENTER_KERNEL \<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ACK_##chip(mask,(nr&amp;7)) \<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &quot;incl &quot;SYMBOL_NAME_STR(intr_count)&quot;\n\t&quot;\&nbsp; /* intr_count为进入临界区的同步信号量 */<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &quot;movl %esp,%ebx\n\t&quot; \<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &quot;pushl %ebx\n\t&quot; \<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &quot;pushl $&quot; #nr &quot;\n\t&quot; \&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* 把do_irq函数参数压进堆栈 */<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &quot;call &quot;SYMBOL_NAME_STR(do_IRQ)&quot;\n\t&quot; \<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &quot;addl $8,%esp\n\t&quot; \<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &quot;cli\n\t&quot; \<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; UNBLK_##chip(mask) \<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &quot;decl &quot;SYMBOL_NAME_STR(intr_count)&quot;\n\t&quot; \<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &quot;incl &quot;SYMBOL_NAME_STR(syscall_count)&quot;\n\t&quot; \<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &quot;jmp ret_from_sys_call\n&quot;);<p>&nbsp;&nbsp;&nbsp; 其中nr为中断请求类型,取值0~15。在irq.c中通过语句BUILD_TIMER_IRQ(first, 0, 0x01)调用该宏,在执行宏的过程中处理时钟中断响应程序do_irq()。<p>&nbsp;&nbsp;&nbsp; 函数do_irq()的第一个参数是中断请求队列序号,时钟中断请求传进来的该参数是0。于是程序根据参数0找到请求队列irq_action[0],逐个处理该队列上handler所指的时钟中断请求的服务函数。由于已经指定时钟中断请求的服务函数是timer_interrupt,在函数timer_interrupt中,立即调用do_timer()函数。<p>&nbsp;&nbsp;&nbsp; 函数do_timer()把jiffies和lost_ticks加1,接着就执行mark_bh(TIMER_BH)函数,把bottom_half中时钟队列对应的位置位,表示该队列处于激活状态。在做完这些动作后,程序从函数do_irq()中返回,继续执行以后的汇编代码。于是,程序在执行语句jmp ret_from_sys_call后,跳到指定的位置处继续执行。<p>代码段jmp ret_from_sys_call及其相关的代码段如下:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ALIGN<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .globl ret_from_sys_call<br>ret_from_sys_call:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmpl $0,SYMBOL_NAME(intr_count)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; jne 2f<br>9:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; movl SYMBOL_NAME(bh_mask),%eax<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; andl SYMBOL_NAME(bh_active),%eax<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; jne handle_bottom_half<br>#ifdef __SMP__<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmpb $(NO_PROC_ID), SYMBOL_NAME(saved_active_kernel_processor)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; jne 2f<br>#endif<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; movl EFLAGS(%esp),%eax&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # check VM86 flag: CS/SS are<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; testl $(VM_MASK),%eax&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # different then<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; jne 1f<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmpw $(KERNEL_CS),CS(%esp)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # was old code segment supervisor ?<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; je 2f<br>1:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sti<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; orl $(IF_MASK),%eax&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # these just try to make sure<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; andl $~NT_MASK,%eax&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # the program doesn't do anything<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; movl %eax,EFLAGS(%esp)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # stupid<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmpl $0,SYMBOL_NAME(need_resched)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; jne reschedule<br>#ifdef __SMP__<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GET_PROCESSOR_OFFSET(%eax)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; movl SYMBOL_NAME(current_set)(,%eax), %eax<br>#else<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; movl SYMBOL_NAME(current_set),%eax<br>#endif<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmpl SYMBOL_NAME(task),%eax&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # task[0] cannot have signals<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; je 2f<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; movl blocked(%eax),%ecx<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; movl %ecx,%ebx&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # save blocked in %ebx for signal handling<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; notl %ecx<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; andl signal(%eax),%ecx<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; jne signal_return<br>2:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RESTORE_ALL<p>ALIGN<br>signal_return:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; movl %esp,%ecx<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pushl %ecx<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; testl $(VM_MASK),EFLAGS(%ecx)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; jne v86_signal_return<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pushl %ebx<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; call SYMBOL_NAME(do_signal)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; popl %ebx<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; popl %ebx<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RESTORE_ALL<p>ALIGN<br>v86_signal_return:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; call SYMBOL_NAME(save_v86_state)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; movl %eax,%esp<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pushl %eax<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pushl %ebx<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; call SYMBOL_NAME(do_signal)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; popl %ebx<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; popl %ebx<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RESTORE_ALL<p>&nbsp; handle_bottom_half:<br>incl SYMBOL_NAME(intr_count)<br>call SYMBOL_NAME(do_bottom_half)<br>decl SYMBOL_NAME(intr_count)<br>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -