当前位置: 首页 > news >正文

网站建设 数据上传 查询/网络营销案例ppt课件

网站建设 数据上传 查询,网络营销案例ppt课件,网站录屏可以做证据吗,web开发用什么软件文章目录基础知识实现中断机制实现单步中断结束语这个系列的最后一篇文章讲述如何实现中断系统,如何实现内置的 1 号中断——单步中断。基础知识 内容来自《汇编语言》第12 章 任何一个通用的 CPU,比如 8086,都具备一种能力,可以…

文章目录

    • 基础知识
    • 实现中断机制
    • 实现单步中断
    • 结束语

这个系列的最后一篇文章讲述如何实现中断系统,如何实现内置的 1 号中断——单步中断。

基础知识

内容来自《汇编语言》第12 章

任何一个通用的 CPU,比如 8086,都具备一种能力,可以在执行完当前正在执行的指令之后,检测到从 CPU 外部发过来的或内部产生的一种特殊信息,并且可以立即对所接收到的信息进行处理。这种特殊的信息,我们可以称其为:中断信息。中断的意思是指,CPU 不再接着向下执行,而是转去处理这个特殊信息。

下面是 8086 CPU 在收到中断信息后,所引发的中断过程。

  1. (从中断信息中)取得中断类型码
  2. 标志寄存器的值入栈(因为在中断过程中要改变标志寄存器的值,所以先将其保存在栈中)
  3. 设置标志寄存器的第 8 位 TF 和第 9 位 IF 的值为0
  4. CS 的内容入栈
  5. IP 的内容入栈
  6. 从内存地址为中断类型码 *4 和中断类型码 *4+2 的两个字单元中读取中断处理程序的入口地址设置 IP 和 CS。

中断处理程序的编写方法:

  1. 保存用到的寄存器
  2. 处理中断
  3. 恢复用到的寄存器
  4. 用 iret 指令返回

单步中断:

基本上,CPU 在执行完一条指令后,如果检测到标志寄存器的 TF 位为 1,则产生单步中断,引发中断过程。单步中断的中断类型码为 1。CPU 提供单步中断功能的原因就是,为单步跟踪程序的执行过程,提供了实现机制。

实现中断机制

我实现的中断机制很简单:中断不能同时发生,中断也没有优先级,哪个中断先产生就先处理。

先在 EU 结构体里最后加上几个中断相关的变量:

type EU struct {ax     uint16cx     uint16dx     uint16bx     uint16sp     uint16bp     uint16si     uint16di     uint16eflags uint16//与 BIU 的通信接口biuCtrl chan BIURequestbiuData chan uint16// 当前正在执行的指令currentInstruction byte// 是否停止执行的标志位stop bool// 是否有内部中断产生innerInterruptOccur boolinnerInterruptType  uint8// 是否有外部中断产生externalInterruptOccur boolexternalInterruptType  uint8// 是否刚执行完 iret 指令retFrominterrupt bool
}

定义产生内部中断、外部中断的方法:

func (e *EU) generateInnerInterrupt(intNum uint8) {e.innerInterruptOccur = truee.innerInterruptType = intNum
}func (e *EU) generateExternalInterrupt(intNum uint8) {e.externalInterruptOccur = truee.externalInterruptType = intNum
}

定义处理中断函数:

// 内置的几个中断类型
const (DivideError uint8 = iotaSingleStepNonMaskableOneByteIntInstructionOverflow
)func (e *EU) processInterrupt(intNum uint8) {// push flagse.pushFlags()// let temp = TFtemp := e.readEFLAGS(tfFlag)// clear IT & TFe.writeEFLAGS(ifFlag, 0)e.writeEFLAGS(tfFlag, 0)// push CS & IPe.pushCS()e.pushIP()// 从中断向量表获取中断处理程序的入口地址addr := 4 * intNumnewIP := e.readMemoryWord(uint32(addr))newCS := e.readMemoryWord(uint32(addr + 2))e.writeSeg(CS, newCS)e.writeIP(newIP)// 如果 TF 标志为为 1,并且发生的中断不是单步中断,那么先执行单步中断if temp == 1 && intNum != SingleStep {e.processInterrupt(SingleStep)}
}

processInterrupt 的函数最后判断 如果 TF 标志为为 1,那么先执行单步中断。因为单步中断是要在执行完一条指令后就必须要执行的,它的优先级要比其他的内部,外部中断优先级高。

修改 EU 的 run 方法,在执行完一条指令后,执行处理中断的逻辑:

func (e *EU) run() {var instructions []bytefor {// 从BIU获取一个字节指令e.biuCtrl <- FetchInstructioninstruction := byte(<-e.biuData)// 拼接指令instructions = append(instructions, instruction)// 解码当前的指令字节序列decodedInstructions := Decode(instructions)// 当前是一条有效的指令if decodedInstructions != nil {// 执行指令e.execute(decodedInstructions)// 清空指令字节序列instructions = instructions[:0]// 如果要求程序终止,则退出循环if e.stop {e.stop = falsebreak}if !e.retFrominterrupt {if e.innerInterruptOccur { // 有内部中断e.innerInterruptOccur = falsee.processInterrupt(e.innerInterruptType)} else {if e.externalInterruptOccur && // 有外部中断e.readEFLAGS(ifFlag) == 1 { // IF == 1e.externalInterruptOccur = falsee.processInterrupt(e.externalInterruptType)}if e.readEFLAGS(tfFlag) == 1 { // TF == 1e.processInterrupt(SingleStep)}}} else {e.retFrominterrupt = false}}}
}

retFrominterrupt 标志位是执行 iret 指令时设置的,这是为了防止循环执行中断!

实现单步中断

实现了中断机制后,就可以实现单步中断。我实现的单步中断程序仅仅是休眠一秒钟。它的中断处理程序非常简单,只有两行汇编语句:

int 22h
iret

原因是我把实际的逻辑都放到执行 int 指令时去做了【为了偷懒,不想写汇编】:

func (e *EU) singleStep() {time.Sleep(1 * time.Second)
}func (e *EU) executeInt(instructions []byte) {if instructions[1] == 0x21 {e.stop = true} else if instructions[1] == 0x22 {e.singleStep()}
}

接下来就是要修改 main 函数将这个中断处理程序【二进制】加载到内存中,并修改中断向量表:

	//装载单步中断程序//cs = 0x2000phyAddr = uint32(0x2000) << 4//单步中断程序执行 int 22h; iretc.writeMemory(phyAddr, []byte{0b11001101, 0x22, 0b11001111})//修改中单步中断的中断向量phyAddr = 1 * 4//	ipc.writeMemory(phyAddr, []byte{0, 0})// csc.writeMemory(phyAddr+2, []byte{0x00, 0x20})// CPU 开始执行程序,第3个参数为是否开启单步调试c.Run(uint16(cs), uint16(programHeader.codeEntryProgOffset), true)

CPU 的 Run 方法修改为添加了一个参数,值为 true 时,就开启单步调试功能:

func (c *CPU) Run(cs, ip uint16, debug bool) {c.biu.run()if debug {c.eu.writeEFLAGS(tfFlag, 1)}c.eu.writeSeg(CS, cs)c.eu.writeIP(ip)c.eu.run()
}

接下来执行程序时,CPU 每执行完一条指令后都会 sleep 1秒。大功告成!

结束语

本系列文章到此就结束了,了解了这些编译器和虚拟机的基本原理及代码实现后,更进一步可以实现编译《汇编语言》书中所有的程序的编译器和运行它们的虚拟机,我本人没有更多精力投入在这方面了,感兴趣的朋友可以去实现!

http://www.jmfq.cn/news/5234401.html

相关文章:

  • 制作网站建设的公司/4p 4c 4r营销理论区别
  • 遵义门户网站/怎么根据视频链接找到网址
  • 网站如何做脚注/网络推广的目标
  • 可以做网站的服务器/网络推广方法的分类
  • 如何查看网站做没做301跳转/如何用模板做网站
  • 好的建设网站/域名被墙查询检测
  • wordpress 图片 不显示缩略图/天津搜索引擎优化
  • 做视频的音乐哪里下载网站/网站seo策划
  • 做民宿推广都有哪些网站/手机优化大师
  • 企业网站建设设计公司/谷歌浏览器下载手机版
  • 网站建设软件培训学校/如何优化网页加载速度
  • 网站兼容ie代码/宁德市蕉城区疫情
  • 智能开关网站开发具体流程/百度seo关键词排名价格
  • 做网站个体户经营范围/武汉网络推广广告公司
  • 网站建设 知乎/湘潭高新区最新新闻
  • 中国建设银行国际互联网站/网站优化公司排名
  • 浏阳网站定制/百度网
  • 东营的网站建设公司/免费打广告网站
  • 用dw怎么做网站后台/潍坊网站建设优化
  • 在网站添加邮箱/seo关键词优化推广外包
  • 专业网站建设哪里有/建站之星
  • 网站建设 java/做什么推广最赚钱
  • 假如做网站推广如何推广/网站注册地址
  • 郑州网站建设咨询/百度怎么优化关键词排名
  • 媒体发稿网站开发/搜索引擎优化的实验结果分析
  • 东莞网站系统后缀/谷歌浏览器app下载安装
  • 提供网站建设课程设计/竞价推广怎么做
  • 基于php mysql的网站开发/河南网站seo靠谱
  • 网站建设不完整(网站内容太少)/商丘seo博客
  • 织梦做动漫网站/开网店怎么推广运营