[290页]

8-2 asm.s程序

8-2-1 功能描述

1、 我们先考虑c)、 d)

2、无出错码
2.1、 将要执行的处理函数压栈;
2.2、 eax被交换入栈。现在eax=护理函数
2.3、 其他寄存压栈
2.4、 立即数0压栈
2.5、 取edx=EIP后,将edx压栈
2.6、 段寄存器都设置0x10段选择符
2.7、 调用处理函数(eax)
2.8、 去掉(2.4和2.5)数据
2.9、 弹出所有寄存
2.10、 返回到应用程序

3、 有出错码
3.1、 将要执行的处理函数压栈;
3.2、 出错码与eax交换;
3.3、 处理函数与ebx交换;
3.4、 其他寄存器压栈;
3.5、 将eax(错误码)压栈;
3.6、 取eax=EIP后,将eax压栈
3.7、 段寄存器都设置0x10段选择符
3.8、 调用处理函数(ebx)
3.9、 去掉(2.4和2.5)数据
3.10、 弹出所有寄存
3.11、 返回到应用程序

8-2-2 代码注释

/**  linux/kernel/asm.s**  (C) 1991  Linus Torvalds*//*
asm.s程序中包括大部分的硬件故障(或出错)处理的低层次代码。
页异常由内存管理程序mm处理,所以不在这里。此程序还处理(希望是这样)由于TS-位而
造成的fpu异常,因为fpu必须正确地进行保存/恢复处理,这些还没有测试过。
*/#本代码文件主要涉及对Intel保留中断int0--int16的处理(int17-int31留作今后使用)。
#以下是一些全局函数名的声明,其原形在traps.c中说明。
.globl _divide_error,_debug,_nmi,_int3,_overflow,_bounds,_invalid_op
.globl _double_fault,_coprocessor_segment_overrun
.globl _invalid_TSS,_segment_not_present,_stack_segment
.globl _general_protection,_coprocessor_error,_irq13,_reserved
.globl _alignment_check#下面这段程序处理无出错号的情况。
#int0 -- 处理被零除出错的情况。 类型:错误; 无错误码。
#在执行DIV或IDIV指令时,若除数是0,CPU就会产生这个异常。当EAX(或AX、AL)容纳
#不了一个合法除操作的结果时,也会产生这个异常。21行标号'_do_divide_error'实际上是
#C语言函数do_divide_error()编译后所生产模块中对应的名称。函数'do_divide_error'在
#traps.c中实现。
_divide_error:pushl $_do_divide_error       #首先把将要调用的函数地址入栈。
no_error_code:                  #这里是无出错号处理的入口处,见下面第56行等。xchgl %eax,(%esp)            #_do_divide_error的地址->eax,eax被交换入栈。pushl %ebxpushl %ecxpushl %edxpushl %edipushl %esipushl %ebppush %ds                  #!!16位的段寄存器入栈后也要占用4个字节。push %espush %fs
33  pushl $0                    # "error code" #将数值0作为出错码入栈。
34  lea 44(%esp),%edx           #取有效地址,即栈中原调用返回地址处的栈指针位置。
35  pushl %edx                  #并压入堆栈。movl $0x10,%edx              #初始化段寄存器ds、es和fs,加载内存数据段选择符。mov %dx,%dsmov %dx,%esmov %dx,%fs
#下面上的'*'号表示调用操作数指定地址处的函数,称为间接调用。这句的含义是调用引起本次异常
#的C处理函数,例如do_divide_error()等。第41行是将堆栈指针加8相当于执行2次pop操作,
#弹出(丢弃)最后入堆栈的两个C函数(33行和35行入栈的值),让堆栈指针重新指向寄存器
#fs入栈处。call *%eax
41  addl $8,%esppop %fspop %espop %dspopl %ebppopl %esipopl %edipopl %edxpopl %ecxpopl %ebxpopl %eax            #弹出原来eax中的内容。iret#int1 -- debug调试中断入口点。处理过程通上。类型:错误/陷阱(Fault/Trap);无错误码。
#当eflags中TF标志置位时而引发的中断。当发现硬件断电(数据:陷阱,代码:错误),或者
#开启了指令跟踪陷阱或任务交换陷阱,或者调用寄存器访问无效(错误),CPU就会产生该异常。
_debug:pushl $_do_int3      # _do_debug #C函数指针入栈。以下同。jmp no_error_code#int2 -- 非屏蔽中断调用入口点。 类型:陷阱; 无错误码。
#这是仅有的被赋予固定中断向量的硬件中断。每当接收到一个NMI信号,CPU内部就会产生中断
#向量2,并执行标志中断应答周期,因此很节省时间。NMI通常保留为极为重要的硬件时间使用。
#当CPU收到一个NMI信号并且开始执行其中断处理过程时,随后所有的硬件中断都将被忽略。
_nmi:pushl $_do_nmijmp no_error_code
#int3 -- 断点指令引起中断的入口点。 类型:陷阱; 无错误码。
#由int 3指令引发的中断,与硬件中断无关。该指令通常由调试器插入被调试程序的代码中。
#处理过程通_debug。
_int3:pushl $_do_int3jmp no_error_code
#int4 -- 溢出出错处理中断入口点。 类型:陷阱; 无错误码。
#EFLAGS中OF标志置位时CPU执行INTO指令就会引发该中断。通常用于编译器跟踪算术计算溢出。
_overflow:pushl $_do_overflowjmp no_error_code#int5 -- 边界检查出错中断入口点。 类型:错误;无错误码。
#当操作数在有效范围以外时引发的中断。当BOUND指令测试失败就会产生该中断。
#BOUND指令有3个操作数,如果第1个不在另外2个之间,就产生异常5
_bounds:pushl $_do_boundsjmp no_error_code#int6 -- 无效操作指令出错中断入口点。 类型:错误;无错误码。
#CPU执行机构检测到一个无效的操作码而引起的中断。
_invalid_op:pushl $_do_invalid_opjmp no_error_code#int9 -- 协处理器段超出出错中断入口点。 类型:放弃;无错误码。
#该异常基本上等同于协处理器出错保护。因为在浮点指令操作数太大时,我们就有这个机会来加载或
#保存超出数据段的浮点值。
_coprocessor_segment_overrun:pushl $_do_coprocessor_segment_overrunjmp no_error_code#int15 -- 其他Intel保留中断的入口点。
_reserved:pushl $_do_reservedjmp no_error_code#int45 -- (0x20+13)Linux设置的数学协处理器硬件中断。
#当协处理器执行完一个操作是就会发出IRQ13中断信号,以通知CPU操作完成。80387在执行计算
#时,CPU会等待其操作完成。下面89行上0xF0是协处理器端口,用于清忙锁存器。通过写该端口,
#本中断将消除CPU的BUSY延续信号,并重新激活80387的处理扩展请求引脚PEREQ。
#该操作主要是为了确保在继续执行8038的任何指令之前,CPU响应本中断。
_irq13:pushl %eaxxorb %al,%al
89  outb %al,$0xF0movb $0x20,%aloutb %al,$0x20jmp 1f
1:  jmp 1f
1:  outb %al,$0xA0popl %eaxjmp _coprocessor_error#以下中断在调用时CPU会在中断返回地址之后将出差号压入堆栈,
#因此返回时也需要将出错号弹出。#int8 -- 双出错故障。 类型:放弃;有错误码。
#通常当CPU在调用前一个异常的处理程序而又监测到偶一个新的异常时,这两个异常会被串行地进行
#处理,但也会碰到很少的情况,CPU不能进行这样的串行处理操作,此时就引发该中断。
_double_fault:pushl $_do_double_fault
error_code:xchgl %eax,4(%esp)       # error code <-> %eaxxchgl %ebx,(%esp)        # &function <-> %ebxpushl %ecxpushl %edxpushl %edipushl %esipushl %ebppush %dspush %espush %fspushl %eax          # error codelea 44(%esp),%eax       # offsetpushl %eaxmovl $0x10,%eaxmov %ax,%dsmov %ax,%esmov %ax,%fscall *%ebxaddl $8,%esppop %fspop %espop %dspopl %ebppopl %esipopl %edipopl %edxpopl %ecxpopl %ebxpopl %eaxiret#int10 -- 无效的任务状态段(TSS)。 类型:错误;有错误码。
#CPU企图切换到一个进程,而该进程的TSS无效。根据TSS中那一部分引起异常,当由于TSS
#长度超过104字节时,这个异常在当前任务产生,因而切换被终止。其他问题则会导致在切换
#后的新任务中产生异常。
_invalid_TSS:pushl $_do_invalid_TSSjmp error_code#int11 -- 段不存在。 类型:错误;有错误码。
#被引用的段不在内存中。段描述符中标志着段不在内存中。
_segment_not_present:pushl $_do_segment_not_presentjmp error_code#int12 -- 堆栈段错误。 类型:错误;有错误码。
#指令操作试图超出堆栈段范围,或者堆栈段不在内存中。这是异常11和13的特例。
#有些 操作系统可以利用这个异常来确定什么时候应该为程序分配更多的栈空间。
_stack_segment:pushl $_do_stack_segmentjmp error_code#int13 -- 一般保护性出差。 类型:错误;有错误码。
#表面是不属于任何其他类的错误。若一个异常产生时没有对应的处理向量(0--16),
#通常就会归到此类。
_general_protection:pushl $_do_general_protectionjmp error_code
#int17 -- 边界对齐检查出错。
#在启用了内存边界检查时,若特权级3(用户级)数据非边界对齐时会产生该异常。_alignment_check:pushl $_do_alignment_checkjmp error_code

剩下中断

#int7 -- 设备不存在(_device_not_available)在kernel/sys_call.s,158行。
#int14 -- 也错误(_page_fault)在mm/page.s,14行。
#int16 -- 协处理器错误(_coprocessor_error)在kernel/sys_call.s,140行
#时钟中断int 0x20(_timer_interrupt)在kernel/sys_call.s,189行。
#系统调用int 0x80(_systme_call)在kernel/sys_call.s,84行。

8-2-3 Intel保留中断向量的定义。

看赵老师表。
表8-2 给出了Intel保留中断向量具体含义的说明。

linux0.12-8-2-asm.s相关推荐

  1. 操作系统学习:Linux0.12初始化详细流程-进程1调度与读取硬盘数据

    本文参考书籍 1.操作系统真相还原 2.Linux内核完全剖析:基于0.12内核 3.x86汇编语言 从实模式到保护模式 4.Linux内核设计的艺术 ps:基于x86硬件的pc系统 Linux0.1 ...

  2. 操作系统学习:系统调用与Linux0.12初始化详细流程

    本文参考书籍 1.操作系统真相还原 2.Linux内核完全剖析:基于0.12内核 3.x86汇编语言 从实模式到保护模式 4.Linux内核设计的艺术 ps:基于x86硬件的pc系统 系统调用 系统调 ...

  3. 编译运行linux0.12,linux0.12 编译过程

    感谢这篇文章的作者:    http://www.cnblogs.com/strugglesometimes/p/4231359.html 编译是个很蛋疼的事情,本想把linux0.12在bochs上 ...

  4. 操作系统学习:Linux0.12文件异步IO

    本文参考书籍 1.操作系统真相还原 2.Linux内核完全剖析:基于0.12内核 3.x86汇编语言 从实模式到保护模式 4.Linux内核设计的艺术 ps:基于x86硬件的pc系统 Linux0.1 ...

  5. 操作系统学习:Linux0.12初始化详细流程-进程退出与系统进入怠速

    本文参考书籍 1.操作系统真相还原 2.Linux内核完全剖析:基于0.12内核 3.x86汇编语言 从实模式到保护模式 4.Linux内核设计的艺术 ps:基于x86硬件的pc系统 Linux0.1 ...

  6. 操作系统学习:Linux0.12初始化详细流程-打开文件与加载可执行程序

    本文参考书籍 1.操作系统真相还原 2.Linux内核完全剖析:基于0.12内核 3.x86汇编语言 从实模式到保护模式 4.Linux内核设计的艺术 ps:基于x86硬件的pc系统 Linux0.1 ...

  7. 操作系统学习:Linux0.12初始化详细流程-进程1加载虚拟盘和根文件系统安装

    本文参考书籍 1.操作系统真相还原 2.Linux内核完全剖析:基于0.12内核 3.x86汇编语言 从实模式到保护模式 4.Linux内核设计的艺术 ps:基于x86硬件的pc系统 Linux0.1 ...

  8. 操作系统学习:Linux0.12初始化详细流程-首个子进程

    本文参考书籍 1.操作系统真相还原 2.Linux内核完全剖析:基于0.12内核 3.x86汇编语言 从实模式到保护模式 4.Linux内核设计的艺术 ps:基于x86硬件的pc系统 Linux0.1 ...

  9. Linux0.12引导启动程序学习笔记(i386)

    // 主题:Linux0.12引导启动程序学习笔记(i386) // 作者:kevinjz2010@gmail.com // 版权:kevinjz原创 // 平台:80386 // 发布日期:2011 ...

  10. linux0.12 编译过程

    感谢这篇文章的作者:    http://www.cnblogs.com/strugglesometimes/p/4231359.html 编译是个很蛋疼的事情,本想把linux0.12在bochs上 ...

最新文章

  1. 所有的编程语言知识,都包含在这100张思维导图里了丨GitHub 13.1k星
  2. PyTorch随笔-0
  3. C语言设备管理器作业,你知道到吗,C语言竟是如何调用硬件的?
  4. Cookie知识点总结
  5. 【VMCloud云平台】SCCM(八) OSD(一)- 部署准备
  6. php ip操作,ip操作 · PHP 个人常用知识总结 · 看云
  7. php 显示探针_UPUPW PHP探针安全版19.08.06
  8. pdfbox创建pdf_使用PDFBox处理PDF文档(新建PDF文件、修改PDF文件、PDF中插入图片、将PDF文件转换为图片)...
  9. 【学习笔记之MYSQL篇】实体联系图
  10. 消息总线/消息中间件/消息队列/服务总线
  11. Sensor 数据整理
  12. html5中播放本地音乐播放器,首款HTML5播放器 支持浏览器内播放本地音乐
  13. 数据库应用之(教育)
  14. Hbase Region的切分与合并【原理分析】
  15. iatf16949标准三大过程_IATF16949要求的过程、文件、记录汇总
  16. MySQL 5.6.21下载安装之安装篇(二)
  17. 什么是promise,promise的使用及实现
  18. 在线网校系统搭建的意义是什么?怎么搭建?
  19. 2015MCM/ICM总结
  20. Java中super()的使用

热门文章

  1. 使用Xilinx Vivado重新设置IP参数时出错
  2. ubuntu 上使用create-ap 打开AP
  3. gdx 源码分析摘录
  4. 【深度长文】细思极恐的YouTube可跳过广告
  5. 模拟量使用计算机电缆,电气线型汇总
  6. Media change: lase insert the disc labled
  7. 金升阳|电源应用问题之应用环境分析
  8. 如何选择漏电保护器规格型号_如何选择漏电保护器型号?漏电保护器的选型原则...
  9. Vue3教程:开发一个 Vue 3 + element-plus 的后台管理系统
  10. SaaS的中年危机(转)