汇编语言学习第九章-转移指令的原理
可以修改IP或同时修改CS和Ip的指令统称为转移指令。概括的讲转移指令就是可以控制CPU执行内存中某处的代码的指令。8086CPU的转移行为有以下几类1只修改IP时称为段内转移比如jmp ax.2)同时修改CS和IP时称为段间转移比如jmp 1000:0.8086 cpu 的转移指令分为以下几类1无条件转移指令如jmp2) 条件转移指令3循环指令如 loop4) 过程5中端9.1 操作符 offsetassume cs:codesg codesg segment start:mov ax,offset start; 相当于mov ax,0 s: mov ax,offset s ; 相当于mov ax,3 codesg ends end start问题9.1有如下程序段填写2条指令使该程序在运行中将s处的一条指令复制到s0处。assume cs:codesg codesg segment s: mov ax,bx ;mov ax,bx 的机器码占两个字节 mov si,offset s mov di,offset s0 ___________ ___________ s0: nop ;nop 的机器码占一个字节 nop codesg ends end s答案为: mov ax,cs:[si]mov cs:[di],ax9.2 jmp 指令jmp 为无条件转移指令可以只修改ip,也可以同时修改cs和ip.jmp 要给出两种信息1转移的目的地址2转移的距离段间转移段内短转移段内近转移9.3 依据位转移进行转移的JMP指令jmp short 短转移IP的修改范围位-128-127.jmp 000B 机器代码EB03 03 这里指的是偏移地址。9.4 转移的目的地址在指令中jmp指令指令 jmp far ptr 标号实现的是段间转移又称为远转移。功能如下cs 标号所在的段的段地址IP标号在段中的偏移地址far ptr 指明了指令用标号的段地址和偏移地址修改cs和ip9.5 转移地址在寄存器中的jmp指令jmp 16位寄存器9.6 转移地址在内存中的jmp指令1jmp word ptr 内存单元地址段内转移2jmp dword ptr 内存端元地址段间转移功能从内存端元地址处开始存放着两个字高地址处的字是转移的目的段地址低地址处事转移的目的偏移地址。cs内存单元地址2ip(内存单元地址)mov ax,0123h mov ds:[0],ax mov word ptr ds:[2],0 jmp dword ptr ds:[0]执行后(cs)0,(ip)0123h, cs:ip 指向00000123mov ax,0123h mov [bx],ax mov word ptr [bx2],0 jmp dword ptr [bx]执行后(cs)0,(ip)0123h,cs:ip 指向0000:0123检测点 9.11程序如下assume cs:code data segment ? data ends code segment start: mov ax,data mov ds,ax mov bx,0 jmp word ptr [bx1] code ends end start若要使程序中的jmp 指令执行后cs:ip 指向程序的第一条指令在data 段中应该定义哪些数据db 0,0debug 调试可以看到ds 和cs 相差16字节。ip 0 [bx1] 设置为0即可。2程序如下assume cs:code data segment dd 12345678h data ends code segment start: mov ax,data mov ds,ax mov bx,0 mov [bx], mov [bx2], jmp dword ptr ds:[0] code ends end start补全 程序使 jmp指令执行后cs:ip 执行程序的第一条指令。分析jmp dword ptr ds:[0] 指令会设置(cs) (data:[2]) (ip)(data:[0])所以答案为mov [bx],bx mov[bx2],cs3) 用debug 查看内存结果如下20001000 BE 00 06 00 00 00 ....则此时CPU执行指令mov ax,2000hmov es,axjmp dword ptr es:[1000H] 后(cs)? (ip)?分析: cs 0006 ip00be9.7 jcxz 指令jcxzJump if CX is Zero指令为有条件转移指令所有的有条件转移指令都是短指令。 在对应的机器码中包含转移的位移而不是目的地址。对ip的修改范围为-128-127监测点9.2补全编程利用jcxz指令实现在内存2000H段中查找第一个值为0的字节找到后将它的偏移地址存储在dx中。assume cs:code code segment start: mov ax,2000h mov ds,ax mov bx,0 s: jmp short s ok:mov dx,bx mov ax,4c00h int 21h code ends end start分析把2000:[bx] 赋值给cx,用jcxz判断cx是否是0如果是0跳转到ok,否则bx 1; 继续循环。请注意这里是字节所以代码为mov cl,[bx]mov ch,0jcxz okinc bx9.8 loop 指令loop 指令为循环指令所有的循环指令都是短转移在对应的机器码中包含转移的位移而不是目的地址。对IP的修改范围都为 -128-127.指令格式: loop 标号((cx)(cx)-1,如果(cx)不等于0转到标号处执行)操作:(1) cxcx-1;(2)如果(cx)不等于0ip(ip)8位位移。8位位移由编译程序在编译时算出。检测点9.3补全编程利用loop指令实现在内存2000H段中查找第一个值为0的byte找到后将它的偏移地址存储在dx中。assume cs:code code segment start: mov ax,2000h mov ds,ax mov bx,0 s:mov cl,[bx] mov ch,0 inc bx loop s ok: dec bx mov dx,bx mov ax,4c00h int 21h code ends end start9.9 根据位移进行转移的意义jmp short 标号jmp near ptr 标号jcxz 标号loop 标号等几种汇编指令它们对IP的修改是根据转移目的地址和转移起始地址之间的位移来进行的。在它们对应的机器码中不包含转移的目的地址而包含的是到目的地址的位移。这种设计方便了程序段在内存中的浮动装配。例如mov cx,5 mov ax,10 s: add ax,ax loop s9.10 编译器对转移位移超界的检测注意根据位移进行转移的指令它们的转移范围受到转移位移的限制如果在源程序中出现了转移范围超界的问题在编译的时候编译器将报错。比如下面的程序将引起编译错误assume cs:code code segment start: jmp short s db 128 dup (0) s:mov ax,0ffffh code ends end startjmp short s 的转移范围是-128-127 IP最多向后移动127个字节。实验8 分析一个奇怪的程序aussume cs:codesg codesg segment mov ax,4c00h int 21h start: mov ax,0 s: nop nop mov di ,offset s mov si,offset s2 mov ax,cs:[si] mov cs:[di],ax s0: jmp short s s1: mov ax,0 int 21h mov ax,0 s2:jmp short s1 nop codesg ends end start分析下面的程序在运行前参考这个程序可以正确返回吗运行后再思考为什么是这种结果分析s 的指令是jmp short s1。s1的偏移量是mov ax,0 int 21h mov ax,0 的大小。实际执行的就是mov ax,4c000h,int 21h mov ax,0;所以程序正常返回。实验9 根据材料编程