CPU结合CS、IP寄存器进行执行程序
上一篇介绍了CS、IP两个寄存器内容,当我们运行一个可执行文件时,我们需要另外一个程序来将这个可执行文件加载到内存当中,关于这个加载可执行文件的程序,我们在这里不管他,点一下即可,一般是通过操作系统的外壳程序(也就是传说中的 Shell 程序),Shell 将可执行文件加载到内存中以后,就会设置 CPU 中的两个寄存器,即设置 CS:IP 两个寄存器指向可执行文件的起始地址,此后 CPU 便从这个起始地址开始读取内存中的指令,并且执行,比如我们在写汇编程序时,通常会使用 START 标记,其实这个标记就是用来标记起始地址的,当将一个汇编程序编译,连接成可执行文件以后,再通过操作系统的 Shell 程序将可执行文件加载到内存中以后,这个 START 所标记处的地址就是整个可执行文件的起始地址了 。也就是说,当一个可执行文件加载到内存中以后,CS:IP 两个寄存器便指向了这个可执行文件的起始地址,然后 CPU 就可以从这个起始地址开始往下读取指令,当读取完指令后,CS:IP 将会自动的改变,基本上是改变 IP ,从而指向下一条要读取的指令,这样就可以执行这个可执行文件了 。
最后再对 CS:IP 总结一下:
(1)你想让CPU执行哪行命令,你就让CS:IP指向保存有那条指令的那块内存即可。
(2)任何时候,CS:IP 执行的地址中的内容都是CPU当前执行的指令。
下面我们来看一个demo,详细观察其执行的过程:
ASSUME CS:CODES CODES SEGMENT START: MOV AX,1234H MOV BX,AX MOV AH,4CH INT 21H CODES ENDS END START
语句的执行过程如下:
从上面的截图可以看出,当我使用 Shell (在 DOS 下也就是 Command 命令解释器)将可执行文件加载进内存后,可以看到,整个程序的起始地址为 0C54H : 0000 H ,并且,可以看到 CS 的地址为 0C54H ,IP 的地址为 0000H,这正好吻合我们上面对 CS:IP 的分析,很明显,CPU 将会读取 MOV AX ,1234H 到 CPU 中并且执行 ,然后我们继续向下看:
可以看到,我们单步执行后,AX 中的值编成了 1234H ,而 IP 寄存器中的值变成了 0003H,对于 AX 中的值的改变,我们是能够理解的,但是 IP 中的值为什么会从 0000H 变到 0003H 呢?从最上面的一幅关于指令在内存中的存放可以看出 MOV AX ,1234H 在内存中需要 3 个内存单元存放,也就是 CPU 为了执行 MOV AX ,1234H 这条指令,已经将内存中相对应的 3 个内存单元读入内存中了,执行完这条指令后,自然,CPU 就要将偏移地址向下移动 3 个单元,从而使得 CS:IP 指向下一条需要执行的指令了 ,为了更深刻的理解,我们再来继续看执行过程,
从最上面的一幅关于指令在内存中的存放可以看出 MOV BX ,AX 在内存中只占 2 个内存单元,这也就是为什么 IP 这一次只向下移动了 2 个单元的缘故 。