30天自制操作系统day22
2015-07-27 13:54
253 查看
栈异常的处理
当在应用程序中访问一个数组时,如果index超过数组的大小,可能会引起栈异常,因为只有访问到位置超过应用程序数据段的范围时才会导致异常。栈异常会触发0x0c中断。处理异常时,最好能够显示发生异常的指令地址。因为中断时,CPU自动PUSH应用程序的EIP,CS,ESP,SS等,可以从栈上获得EIP。
中断后又执行了
PUSH ES PUSH DS PUSHAD
所以栈上保存的数据是
esp[0]: EDI esp[1]: ESI esp[2]: EBP esp[3]: ESP esp[4]: EBX esp[5]: EDX esp[6]: ECX esp[7]: EAX esp[8]: DS esp[9]: ES esp[10]: 错误编号 esp[11]: EIP esp[12]: CS esp[13]: EFLAGS esp[14]: ESP esp[15]: SS
其中,0-7是PUSHAD,10-15是中断时CPU自动PUSH的,CS:EIP指向中断时应用程序运行的位置,SS,ESP是应用程序的数据段号和栈地址。所以昨天没弄明白的地方可以解释了。CPU自动做了CS,EIP,SS,ESP的切换。返回时需要
ADD ESP,4是为了跳过
esp[10]:错误编号,这时栈上有EIP和CS,就可以IRETD返回了。
在中断处理函数中获取esp[11],打印,就能知道发生异常的地址了。
强制结束任务
就像Linux里CTRL+C那样,需要一个按键用了强制结束任务,避免死循环。由于console_task正在执行应用程序,无法接受输入,所以在bootpack.c的处理键盘输入时进行。结束任务的代码:
io_cli(); task_cons->tss.eax = (int) &(task_cons->tss.esp0); task_cons->tss.eip = (int) asm_end_app; io_sti();
实际上是跳转到了asm_end_app:
_asm_end_app: MOV ESP,[EAX] MOV DWORD [EAX+4],0 POPAD RET
在start_app()时,我们把操作系统的ESP放到了tss->esp0的位置。结束任务时,把&tss->esp0赋给EAX,然后在_asm_end_app中恢复到ESP中。
用C语言显示字符串
之前写的汇编程序,显示字符串没问题。但如果是用C语言写的就出错。原因是编译出来的.hrb文件中,包含代码部分和数据部分。这些部分的位置,大小会写在文件头中。如果没有把数据部分复制到相应的地址去,就会访问不到。.hrb文件头部主要包括:
0x0000 需要操作系统为程序准备的数据段大小(包括了栈的大小) 0x000c ESP的初始值、数据段的起始位置 0x0010 数据段中数据部分的大小(不包括栈大小) 0x0014 .hrb文件内,数据部分的位置(需要从这里开始复制)
所以在cmp_app()中需要做如下修改:
segsiz = *((int *) (p + 0x0000)); esp = *((int *) (p + 0x000c)); datsiz = *((int *) (p + 0x0010)); dathrb = *((int *) (p + 0x0014)); q = (char *) memman_alloc_4k(memman, segsiz); *((int *) 0xfe8) = (int) q; set_segmdesc(gdt + 1003, finfo->size - 1, (int) p, AR_CODE32_ER + 0x60); set_segmdesc(gdt + 1004, segsiz - 1, (int) q, AR_DATA32_RW + 0x60); for (i = 0; i < datsiz; i++) { q[esp + i] = p[dathrb + i]; }
分配数据段q,大小为segsiz,从esp开始,将代码段p中datahrb开始的datsiz个字节复制过来。也就是数据部分刚好在栈的上面。
显示窗口的API
显示窗口的API大体和显示字符的API一样,都是将参数放入寄存器然后中断。但是显示窗口需要窗口的SHEET结构作为返回值。返回值放在EAX中。在中断调用asm_hrb_api()时,用了两次PUSHAD,分别是保存旧值和传参数。可以直接将SHEET结构的地址直接写到栈上,具体是写到第一次PUSHAD中的EAX中。最后POPAD就可以放到EAX里了。
得到了SHEET结构,又可以添加在窗口显示字符等API了。
相关文章推荐
- 工作经验应该这么写,有模板哦!
- 基于Monkey的Android自动化测试
- c++ bitset与位压缩
- LeetCode 237 : Delete Node in a Linked List
- 201507271337_《Backbone之三——Event、Controller(Router)、View、Collection、Model》
- ExtJs和JQuery应用的比较
- 一个让你学习SQL语句的教程
- ubuntu安装jdk之后,报错java/lang/NoClassDefFoundError: java/lang/Object的解决办法
- Android 防止快速 点击 多次
- 利用shell脚本批量复制文件到给定目录
- mybatis中关于传入参数parameterType
- django 1.8 官方文档翻译: 3-4-2 内建显示视图
- HDU 5296 Annoying problem
- AT&T计划削减支出 SDN头功
- 利用Toolbar和SlidingTabLayout实现Tab
- 最小费用最大流模板
- Hadoop2.5+HA+zk3.4.6集群搭建
- InnoDB特性之-两次写
- sqlite3编绎
- SAP IDES ECC 6.0安装完后,没有数据