计算机采取"存储程序与程序控制"的工作方式,即事先把程序加载到计算机的存储器中,当启动运行后,计算机便会自动按照程序的要示进行工作。
为了进一步说明微机的工作过程,我们来具体讨论一个模型机怎样执行一段简单的程序。例如,计算机如何具体计算3+2=?虽然这是一个相当简单的加法运算,但是,计算机却无法理解。人们必须要先编写一段程序,以计算机能够理解的语言告诉它如何一步一步地去做,直到每一个细节都详尽无误,计算机才能正确地理解与执行。为此,我们在启动工作计算机之前做好如下几项工作:
①首先用助记符号指令编写源程序。
②由于机器不能识别助记符号,需要翻译(汇编)成机器语言指令。
假设上述①、②两步我们已经做了。
③将数据和程序通过输入设备送至存储器中存放,整个程序一共3条指令,5个字节,假设它们存放在存储器从00H单元开始的相继5个存储单元中。
1.执行一条指令的过程
计算机机招待程序时是一条指令一条指令地执行的。执行一条指令的过程可分为两个阶段,如图1-6所示。
首先,CPU进入以指令阶段,从存储器中取出指令码送到指令寄存器中寄存,然后对该指令译码后,再转入执行指令阶段,在这期间,CPU执行指令指定的操作。
取指令阶段是由一系列相同的操作组成的,因此,取指令阶段的时间总是相同的。而执行指令的阶段是由不同的事件顺序组成的,它取决于被执行指令的类型。执行完一条指令后接着执行下一条指令,即:
取指 执指,取指 执指……如此反复,直至程序结束。
2.执行程序的过程
开始执行程序时,必须先给程序计数器PC赋以第一条指令的首地址00H,然后就进入第一条指令的取令的取指令阶段。
第一条指令的执行过程:
取指令阶段:
①将程序计数器PC的内容(00H)送至地址寄存器AR,记为PC AR。
②程序计数器PC的内容自动加1变为01H,为取下一个指令字节作准备,记为PC+1 PC。
③地址寄存器AR将00H通过地址总线送至存储器,经地址译码器译码,选中00号单元,记为AR M。
④CPU发出"读"命令。
⑤所选中的00号单元的内容B0H读至数据总线DB,记为(00H) DB。
⑥经数据总线DB,将读出的B0H送至数据寄存器,记为DB DR。
⑦数据寄存器DR将其内容送至指令寄存器IR,经过译码,控制逻辑发出招待该条指令的一系列控制信号,记为DR IR,IR ID、PLA。经过译码,CPU"识别"出这个操作码就是MOV A,03指令,于是,它"通知"控制器发出执行这条指令的各种控制命令。这就完成了第一条指令的取指令阶段,上述过程如图所示。(点击看java动画演示)
1执行指令阶段:
经过对操作码B0H译码后,CPU就"知道"这是一条把下一单元中的立即数取入累加器A的指令。所以,执行第一条指令就必须把指令第二字节中的立即数取出来送至累加器A,取指令第二字节的过程为:
①PC AR,即将程序计数器的内容01H送至地址器AR。
②PC+1 PC,即将程序计数器的内容处动加1变为02H,为取下一条指令作准备。
③AR M,即地址寄存器AR将01H通过地址总线送至存储器,经地址译码选中01H单元。
④CPU发出"读"命令。
⑤(01H) DB,即选中的01H存储单元的内容03H读至数据总线DB上。
⑥DB DR,即通过数据总线,把读出的内容03H送至数据寄存器DR。
⑦DR A,因为经过译码已经知道读出的是立即数,并要求将它送到累加器A,故数据寄存器DR通过内部数据总线将03H送至累加器A。
上述过程如图所示。(点击看java动画演示)
第二条指令的执行过程:
第一条指令执行完毕以后,进入第二条指令的执行过程。
取指令阶段:
这个过程与取第一条指令的过程相似。
执行指令阶段:
经过对指令操作码04H的译码后,知道这是一条加法指令,它规定累加器A中的内容与指令第二字节的立即数相加。所以,紧接着执行把指令的第二字节的立即数02H取出来与累加器A相加,其过程为:
①把PC的内容03H送至AR,记为PC AR。
②当把PC内容可靠地送至AR以后,PC自动加1,记为PC+1 PC。
③AR通过地址总线把地址03H送至存储器,经过译码,选中相应的单元,记为AR M。
④CPU发出"读"命令。
⑤选中的03H存储单元的内容02H读出至数据总线上,记为(03H) DB。
⑥数据通过数据总线送至DR,记为DB DR。
⑦因由指令译码忆知读了的为操作数,且要与A中的内容相加,故数据由DR通过内部数据总线送至ALU的另一输入端,记为DR ALU。
⑧累加器A中的内容送ALU,且执行加法操作,记为A ALU。
⑨相加的结果由ALU输出至累加器A中,记为ALU A。第二条指令的执行过程如图1-10所示。至此,第二条指令的执行阶段结束了,就转入第三条指令的取指令阶段。
按上述类似的过程取出第三条指令,经译码后就停机。这样,微计算机就完成了人们事先编制的程序所规定的全部操作要求。
总之,计算机的工作过程就是执行指令的过程,而计算机执行指令的过程可看成是控制信息在计算机各组成部件之间的有序流动过程。信息是在流动过程中得到相关部件的加工处理。因此,计算机的主要功能就是如何有条不紊地控制大量信息在计算机各部件之间有序地流动,其控制过程类似于铁路交通管理过程。为此,人们必须事先制定好各次列车运行图(相当于计算机中的信息传送通路)与列车时刻表(相当于信息操作时间表),然后,再由列车调度室在给定的时刻发出各种控制信号,如交通管理中的红、绿灯、扳道信号等(相当于计算机中的各种微操作控制信号。通常情况下,CPU执行指令时,把一条指令的操作分成若干个如上所述的微操作,顺序完成这此微操作,就完成了一条指令的操作),以保证列车按照预定的路线运行。
----------------------------------------------------------------------------------------------------------------------
【微型计算机中程序的执行过程】 在保护模式下,处理器会在一些特殊情况下产生 “异常”中断,也就是出现某种特定情况,就终止当前正在执行的程序,跳转到一个(由操作系统指定的)中断处理函数。根据 异常中断 的不同,以及其他情况,选择是否跳回原先执行的程序,或是启动其他程序,或是干脆宕机。
此表是处理器已经定下的,内部中断。
中断向量号触发原因
0x00除零错
0x01调试异常
0x02非可屏蔽中断 (NMI)
0x03断点 (INT 3 指令)
0x04溢出 (INTO 指令)
0x05越界 (BOUND 指令)
0x06无效的指令
0x07无协处理器
0x08双重错误
0x09协处理器越界
0x0A无效的 TSS
0x0B段不存在
0x0C栈溢出
0x0D通用保护异常(内存引用或其他检查保护),Windows 9x 蓝屏就是它的杰作
0x0E页错误
0x0FIntel 保留
0x10协处理器错误
0x11-0x19Intel 保留 在运行时,触发这些中断,有可能是程序无意间发生的(程序员没写好代码,或是操作系统的错误),还有可能是程序自动故意引发的(比如执行 ud2 汇编指定,会产生 中断向量号为 0x06 的 无效指令 异常中断)
仔细看看,可以发现中断向量号为0x01 的叫做 调试异常 的异常中断。说明这个是专门留给操作系统和程序作为调试用的。
怎么利用调试异常中断 来制作调试器呢?
首先,程序执行前,需要通过一个叫做 加载器 的东西 将二进制机器指令从外存(硬盘,u盘等)加载到内存里面。加载器在加载程序时,会根据程序的执行文件类型,做一些处理(具体的和调试器没什么关系,就不解释了)。
而调试器,可以看做是一个特殊的加载器,它会在加载程序时,在每一个机器指令间,插入一条调试异常中断指令(int 0x01)。然后,在加载的程序执行时,每执行一条机器指令,就会引发一个调试异常,然后调试器从操作系统的调试异常处理函数那里接过执行权,进行判断,是否在这条指令后设置了调试断点?若设置了,就中断下来,显示程序与cpu寄存器的状态等直到用户按下继续执行的按钮。若没有设置调试断点,就将执行权交回给被调试的程序继续执行下一条指令,然后再触发调试异常中断。。。。。如此不断循环判断执行,直到结束。
(由于每条指令,都会进行这些判断,被调试的程序执行速度,一般与正常状态下的执行速度慢上好几个数量级)
以上,就是调试器的基本原理,更多的信息,你可以到 看雪 之类的网站看看