前言
在汇编语言中,CS(Code Segment)和IP(Instruction Pointer)寄存器是与代码执行密切相关的两个重要寄存器。它们与代码段直接关联,通过jmp(Jump)指令,程序能够实现无条件跳转到指定的代码段和偏移地址。本文将深入探讨CS、IP寄存器、代码段的关系,以及jmp指令的作用和使用。
一、CS和IP寄存器与代码段的关系
1.1 CS和IP寄存器的演示
CS寄存器(代码段寄存器): CS寄存器存储了当前执行的指令所在的代码段的起始地址。它是一个16位寄存器,指示了代码在内存中的位置。CS寄存器的值与代码段的段基址相关,形成了代码段的起始物理地址。
IP寄存器(指令指针寄存器): IP寄存器存储了当前执行指令的偏移地址,它指示了代码段中的具体位置。IP寄存器的值与代码段的偏移地址相关,决定了程序执行的下一条指令。
8086CPU当前状态:CS中内容为2000H,IP中内容为0000H
内存20000H~20009H处存放着可执行的机器代码
1.2 8086PC读取和执行指令演示
8086PC工作过程的简要描述:
(1)从CS:IP指向内存单元读取
指令,读取的指令进入指
令缓冲器;
(2)IP = IP + 所读取指令的长
度,从而指向下一条指令;
(3)执行指令。 转到步骤
(1),重复这个过程。
二、用汇编语言写源程序
2.1 汇编程序是什么
汇编程序:包含汇编指令和伪指令的文本
2.2 工作过程
2.3 汇编程序结构
assume cs:code code segment mov ax,10 add ax,10 mov ax,4c00h int 21h code ends end
其中
code segment
code ends end
为伪代码
mov ax,10 add ax,10 mov ax,4c00h int 21h
为汇编指令
其中
mov ax,4c00h int 21h
程序返回(套路!):程序结束运行后,将
CPU的控制权交还给使它得以运行的程序
(常为DOS系统)。
2.4 程序中的三种伪指令
1、段定义
一个汇编程序是由多个段组成的,这些段被用来存放代码、数据
或当作栈空间来使用。
一个有意义的汇编程序中至少要有一个段,这个段用来存放代码。
定义程序中的段:每个段都需要有段名
段名 segment ——段的开始 .... 段名 ends ——段的结束
2、end (不是ends)
汇编程序的结束标记。若程序结尾处不加end,编译器在编译程序
时,无法知道程序在何处结束。
3、assume(假设)
含义是假设某一段寄存器和程序中的某一个用 segment … ends 定
义的段相关联——assume cs:codesg指CS寄存器与codesg关联,将
定义的codesg当作程序的代码段使用。
2.5 编译和链接
由写出源程序到执行可执行文件的过程
编译
我们在DOSBox里面输入下面的指令
masm your.asm
其中这些提示分别是:
1、目标文件(.OBJ)是我们
对一个源程序进行编译要
得到的最终结果。
2、列表文件(.LST)是编译
器将源程序编译为目标文
件的过程中产生的中间结
果。
3、交叉引用文件(*.CRF)同
列表文件一样,是编译器
将源程序编译为目标文件
过程中产生的中间结果。
:对源程序的编译结束,编
译器输出的最后两行告诉
我们这个源程序没有警告
错误和必须要改正的错误。
我们现在按回车不管即可。
链接
我们直接使用下面这个命令即可链接:
link yourname
他的提示的意义如下:
1、可执行文件(.EXE)是我们对一个程序进行连接要得到的
最终结果。
2、映像文件(.MAP)是连接程序将目标文件连接为可执行
文件过程中产生的中间结果。
3、库文件(.LIB)里包含了一些可以调用的子程序,如果我
们的程序中调用了某一个库文件中的子程序,就需要
在连接的时候,将这个库文件和我们的目标文件连接
到一起,生成可执行文件。
:no stack segment,一个“没有栈段”的警告错误 ,可
以不理会这个错误
执行可执行文件
直接输入下面这个命令即可,yourname是你的exe名称
yourname
2.6 用Debug跟踪程序执行
首先,我们需要使用debug打开我们的exe
debug your.exe
接下来我们可以使用u去查看cs:ip里面的代码
然后我们可以使用t命令单步执行
除了r命令,我们还可以使用p命令,p命令和r命令几乎是一样的,只不过在我们的
int 21h
这个汇编指令执行完后会提示
继续命令P(Proceed):类似T命令,逐条执行指令、显示结果。但遇子程序、中断等时,直接执行,然后显示结果。
运行命令G(Go):从指定地址处开始运行程序,直到遇到断点或者程序正常结束。
三、jmp跳转指令
3.1 事实
事实:执行何处的指令,取决于CS:IP
应用:可以通过改变CS、IP中的内容,来控制CPU要执行的目标指令
问题:如何改变CS、IP的值?
方法1:Debug 中的 R 命令可以改变寄存器的值——rcs, rip
Debug是调试手段,并非程序方式!
方法2:用指令修改
mov cs, 2000H mov ip, 0000H
8086CPU不提供对CS
和IP修改的指令!
方法3:转移指令 jmp
3.2 jmp指令
同时修改CS、IP的内容
jmp 段地址:偏移地址
jmp 2AE3:3 jmp 3:0B16
功能:用指令中给出的段地址修改CS,偏移地址修改IP。
仅修改IP的内容
jmp 某一合法寄存器
jmp ax (类似于 mov IP, ax) jmp bx
功能:用寄存器中的值修改IP。
3.3 问题分析
从20000H开始,执行的序列是:
(1)mov ax,6622
(2)jmp 1000:3
(3)mov ax,0000
(4)mov bx,ax
(5)jmp bx
(6)mov ax,0123H
(7)转到第(3)步执行