06day 分割编译与中断处理
来源:互联网 发布:爱拍录像软件 编辑:程序博客网 时间:2024/05/10 08:06
分割编译:
1.将不同功能的实现写到不同的c文件中
2.修Makefile普通规则为一般规则
%.gas : %.c Makefile $(CC1) -o $*.gas $*.c%.nas : %.gas Makefile $(GAS2NASK) $*.gas $*.nas%.obj : %.nas Makefile $(NASK) $*.nas $*.obj $*.lst
3.提取声明部分到.h文件中,减少冗余代码。
接下来说历史遗留问题:
_load_gdtr: ; void load_gdtr(int limit, int addr); MOV AX,[ESP+4] ; limit MOV [ESP+6],AX LGDT [ESP+6] RET
这个函数将指定的 段上限和地址值 赋给名为GDTR的48位寄存器。
>
limit 0x0000ffff
esp+4 FF
esp+5 FF
esp+6 00
esp+7 00
addr 0x00270000
esp+8 00
esp+9 00
esp+0a 27
esp+0b 00
栈的格式如上,我们把FFFF拷贝到 ESP+6 处 然后把 ESP+6~~ESP+0B 处的数据作为GDTR,所以GDTR前16位是段限,后32位是地址。
IDTR也是同理的。
_load_idtr: ; void load_idtr(int limit, int addr); MOV AX,[ESP+4] ; limit MOV [ESP+6],AX LIDT [ESP+6] RET
struct SEGMENT_DESCRIPTOR { short limit_low, base_low;// 2 + 2 char base_mid, access_right;// 1 + 1 char limit_high, base_high;// 1 + 1 };//正好8字节void set_segmdesc(struct SEGMENT_DESCRIPTOR *sd, unsigned int limit, int base, int ar){ if (limit > 0xfffff) { ar |= 0x8000; /* G_bit = 1 */ limit /= 0x1000; } sd->limit_low = limit & 0xffff; sd->base_low = base & 0xffff; sd->base_mid = (base >> 16) & 0xff; sd->access_right = ar & 0xff; sd->limit_high = ((limit >> 16) & 0x0f) | ((ar >> 8) & 0xf0); sd->base_high = (base >> 24) & 0xff; return;}
接下来说说是如何用8个字节64位来表示段的属性的。段的属性有 大小,起始地址,管理属性(写入,执行,系统专用?)
段的地址,用base_low ,base_mid,base_high ,正好32位来表示。将地址分段是为了与80286兼容。
在剩下32位中,段上限只能使用20位,那么如何用20位的长度来表示32位的地址空间呢(也就是4GB空间),在段的属性里设置了一个标志位Gbit,如果标示位为1的时候,limit的单位解释为页,一页指4KB, 所以 1M*4KB=4GB。
而limit由limit_low和limit_high组成,一共有24位,其实我们要把段的属性写入limit_high的上4位中,所以段上限还是20位.
12位段属性中,高4位放在limit_high的高4位里,所以我们可以把ar当做16位处理 xxxx0000xxxxxxxx
高4位成为扩展访问权,这4位在80286的时代还不存在,386之后可以使用,这4位是GD00 G就是Gbit ,D是指段的模式,D=1表示32位,D=0表示16位模式。 这里的16位模式只能运行286的程序 不能调用BIOS。 我们通常使用D=1 32模式
ar的低8位:
接着说中断处理就要说PIC的寄存器。
IMR寄存器 interrupt mask register 中断屏蔽寄存器,8位,如果某一位是1,对应的IRQ信号被屏蔽。
ICW寄存器 initial control word 初始化控制寄存器
ICW寄存器有4个 ICW1 ICW2 ICW3 ICW4
ICW3是有关主从连接的设定,对应某位置为1表示驱动该位的从PIC,这里我们设置为 00000100 表示驱动2号位从PIC。
#include "bootpack.h"void init_pic(void)/* PIC偺弶婜壔 */{ io_out8(PIC0_IMR, 0xff ); /* 禁止所有中断 */ io_out8(PIC1_IMR, 0xff ); /* 禁止所有中断 */ io_out8(PIC0_ICW1, 0x11 ); /* 边沿触发 */ io_out8(PIC0_ICW2, 0x20 ); /* IRQ0-7由INT20-27接受 */ io_out8(PIC0_ICW3, 1 << 2); /* PIC1偼IRQ2偵偰愙懕 */ io_out8(PIC0_ICW4, 0x01 ); /* 无缓冲区模式 */ io_out8(PIC1_ICW1, 0x11 ); /* 边沿触发 */ io_out8(PIC1_ICW2, 0x28 ); /* IRQ8-15由INT28-2f接受 */ io_out8(PIC1_ICW3, 2 ); /* PIC1由IRQ2连接 */ io_out8(PIC1_ICW4, 0x01 ); /* 无缓冲区模式 */ io_out8(PIC0_IMR, 0xfb ); /* 11111011 PIC1以外全部禁止 */ io_out8(PIC1_IMR, 0xff ); /* 11111111 禁止所有中断 */ return;}
这次我们以INT 0X20~0X2F接受中断信号 IRQ0~15
接下来制作我们的中断处理程序
void inthandler21(int *esp)/* 来自PS/2键盘的中断 */{ struct BOOTINFO *binfo = (struct BOOTINFO *) ADR_BOOTINFO; boxfill8(binfo->vram, binfo->scrnx, COL8_000000, 0, 0, 32 * 8 - 1, 15); putfonts8_asc(binfo->vram, binfo->scrnx, 0, 0, COL8_FFFFFF, "INT 21 (IRQ-1) : PS/2 keyboard"); for (;;) { io_hlt(); }}void inthandler2c(int *esp)/* PS/2鼠标 */{ struct BOOTINFO *binfo = (struct BOOTINFO *) ADR_BOOTINFO; boxfill8(binfo->vram, binfo->scrnx, COL8_000000, 0, 0, 32 * 8 - 1, 15); putfonts8_asc(binfo->vram, binfo->scrnx, 0, 0, COL8_FFFFFF, "INT 2C (IRQ-12) : PS/2 mouse"); for (;;) { io_hlt(); }}
中断程序写好之后 我们要注册中断程序,
set_gatedesc(idt + 0x21, (int) asm_inthandler21, 2 * 8, AR_INTGATE32); set_gatedesc(idt + 0x27, (int) asm_inthandler27, 2 * 8, AR_INTGATE32);
void set_gatedesc(struct GATE_DESCRIPTOR *gd, int offset, int selector, int ar){ gd->offset_low = offset & 0xffff; gd->selector = selector; gd->dw_count = (ar >> 8) & 0xff; gd->access_right = ar & 0xff; gd->offset_high = (offset >> 16) & 0xffff; return;}
make run运行后 我们发现可以成功相应键盘中断,但是却不能响应鼠标中断。
- 06day 分割编译与中断处理
- 6、分割编译与中断处理
- 第6天 分割编译与中断处理
- [读书笔记]30 天自制操作系统 day6 分割编译与中断处理
- 六、分割源文件和中断处理
- 中断与异常处理
- 异常与中断处理
- 中断与中断处理(二)
- 第6章 中断与中断处理
- 中断处理程序与中断服务例程
- 中断处理程序与中断服务例程
- 异常处理与程序中断
- 进程切换与中断处理
- matlab 图像形态学处理与图像分割
- 数字图像处理06(图像分割)
- uc/os软件中断与硬件中断处理流程分析
- Linux内核设计与实现(8)---中断和中断处理
- Linux内核学习7:中断与中断处理(1)
- 队列
- Android 中 单元测试的配置
- UISearchDisplayController点击搜索时屏幕顶部出现黑条问题的解决方案
- C++学习笔记
- 红米2移动稳定版 刷开发版本
- 06day 分割编译与中断处理
- AlexNet论文翻译
- python初学selenium+phantomjs遇到的问题
- Eclipse RCP 插件开发中经常调用的几个方法
- dos下,sqlplus导入导出出oracle数据库_用户和表
- 【bzoj2096】[Poi2010]Pilots 单调队列
- MySQL数据库拼接指定长度的数字字符串
- 11黑色 referer
- javaweb通过jdbc连接数据库