push ds ; ┃ push es ; ┣ 保存原寄存器值 push fs ; ┃ push gs ; ┛ inc byte [gs:0] ; 改变屏幕第 0 行, 第 0 列的字符 mov al, EOI ; ┓reenable master 8259 out INT_M_CTL, al ; ┛ pop gs ; ┓ pop fs ; ┃ pop es ; ┣ 恢复原寄存器值 pop ds ; ┃ popad ; ┛
sub esp, 4 pushad ; ┓ push ds ; ┃ push es ; ┣ 保存原寄存器值 push fs ; ┃ push gs ; ┛ mov dx, ss mov ds, dx mov es, dx inc byte [gs:0] ; 改变屏幕第 0 行, 第 0 列的字符 mov al, EOI ; ┓reenable master 8259 out INT_M_CTL, al ; ┛ lea eax, [esp + P_STACKTOP] mov dword [tss + TSS3_S_SP0], eax pop gs ; ┓ pop fs ; ┃ pop es ; ┣ 恢复原寄存器值 pop ds ; ┃ popad ; ┛ add esp, 4 iretd
56 sub esp, 4 157 pushad ; ┓ 158 push ds ; ┃ 159 push es ; ┣ 保存原寄存器值 160 push fs ; ┃ 161 push gs ; ┛ 162 mov dx, ss 163 mov ds, dx 164 mov es, dx 165 166 mov esp, StackTop ; 切到内核栈 167 168 inc byte [gs:0] ; 改变屏幕第 0 行, 第 0 列的字符 169 170 mov al, EOI ; ┓reenable master 8259 171 out INT_M_CTL, al ; ┛ 172 173 push clock_int_msg 174 call disp_str 175 add esp, 4 176 177 mov esp, [p_proc_ready] ; 离开内核栈; 178 179 lea eax, [esp + P_STACKTOP] 180 mov dword [tss + TSS3_S_SP0], eax 181 182 pop gs ; ┓ 183 pop fs ; ┃ 184 pop es ; ┣ 恢复原寄存器值 185 pop ds ; ┃ 186 popad ; ┛ 187 add esp, 4 188 189 iretd
156 sub esp, 4 157 pushad ; ┓ 158 push ds ; ┃ 159 push es ; ┣ 保存原寄存器值 160 push fs ; ┃ 161 push gs ; ┛ 162 mov dx, ss 163 mov ds, dx 164 mov es, dx 165 166 mov esp, StackTop ; 切到内核栈 167 168 inc byte [gs:0] ; 改变屏幕第 0 行, 第 0 列的字符 169 170 mov al, EOI ; ┓reenable master 8259 171 out INT_M_CTL, al ; ┛ 172 sti 173 push clock_int_msg 174 call disp_str 175 add esp, 4 176 push 1 call delay add esp,4 cli 177 mov esp, [p_proc_ready] ; 离开内核栈; 178 179 lea eax, [esp + P_STACKTOP] 180 mov dword [tss + TSS3_S_SP0], eax 181 182 pop gs ; ┓ 183 pop fs ; ┃ 184 pop es ; ┣ 恢复原寄存器值 185 pop ds ; ┃ 186 popad ; ┛ 187 add esp, 4
改动代码之后,运行结果:
为什么会不停打印“^”呢?因为中断发生以后,没有结束就会出发下一个时钟中断,永远没能从中断处理函数中返回。为了改变这种情况,我们需要将中断改成不可重入的,我们现在使用一个全局变量来解决这个问题。代码如下:(我们需要在global中增加变量的定义和声明,在main函数中将变量初始化)
169 mov al, EOI ; ┓reenable master 8259 170 out INT_M_CTL, al ; ┛ 171 172 inc dword[k_reenter] 173 cmp dword[k_reenter],0 174 jne .re_enter 175 176 sti 177 178 mov esp, StackTop ; 切到内核栈 179 push clock_int_msg 180 call disp_str 181 add esp, 4 182 183 push 1 184 call delay 185 add esp,4 186 187 cli 188 189 mov esp, [p_proc_ready] ; 离开内核栈; 190 191 lea eax, [esp + P_STACKTOP] 192 mov dword [tss + TSS3_S_SP0], eax 193 194 .re_enter: 195 dec dword[k_reenter]
改动以后,运行结果如下: