王爽 《汇编语言》 读书笔记 九 转移指令的原理

来源:互联网 发布:常州数控编程培训 编辑:程序博客网 时间:2024/06/11 07:28

第九章  转移指令的原理


可以修改,或同时修改CS和IP的指令统称为转移指令。

只修改IP   jmp ax

同时修改CS和IP   jmp  1000:0


无条件转移指令jmp

条件转移指令

循环指令

过程

中断


9.1 操作符 offset

由编译器处理的符号 取得标号的偏移地址

start : mov ax, offset start

s: mov ax, offset s

将S处的代码复制到S0处

assume cs:codecode segments:mov ax, bxmov si, offset smov di, offset s0mov ax, cs:[si]mov cs:[di], axs0:nopnopcode endsend

运行结果


9.2 jmp指令

jmp给出两种信息

1)转移的目标地址

2)转移的距离(段间转移,段内转移,段内近转移)


9.3 依据位移进行转移段jmp指令

jmp short 标号   段内短转移对IP对修改范围在 -128~127

例子

assume cs:codecode segmentstart:mov ax, 0jmp short sadd ax, 1s:inc axcode endsend start

编译后在debug中对机器码


jmp short s0 被编译成  EB03  并不包含目标地址

CPU在执行jmp指令的时候并不需要转移的目的地址

EB03 表示在当前IP基础上向后位移3个字节的地址 也就是  jmp short  s  编译以后包含的数据是位移量

jmp short 标号    (IP) = (IP) + 8位位移量

1)8位位移=标号处的地址-jmp指令后的第一个字节的地址

2)short指明此处的位移为8位位移

3)8位位移的范围是-128~127,用补码表示

4)8位位移由编译程序在编译时算出

还有一种

jmp near ptr 标号   (IP)= (IP)+16位位移

1)16位位移=标号处的地址-jmp指令后的第一个字节的地址

2)near ptr指明此处的位移为16位位移,进行段内近转移

3)16位位移的范围是-32768~32767,用补码表示

4)16位位移由编译程序在编译时算出


9.4 转移的目的地址在指令中的jmp指令

assume cs:codecode segmentstart:mov ax, 0mov bx, 0jmp far ptr sdb 256 dup (0)s:add ax, 1inc axcode endsend start


9.5 转移地址在寄存器中的jmp指令

jmp 16位reg

功能 (IP) = (16位reg)


9.6 转移地址中内存中的jmp指令

1)jmp word ptr 内存单元地址(段内转移)

jmp word ptr ds:[0]


jmp word ptr [bx]

2)jmp dword ptr 内存单元地址(段间转移)

二个字单元,高地址字单元存放段地址,低地址字单元存放偏移地址


(CS) = (内存单元地址+2)

(IP) = (内存单元地址)


9.7 jcxz 指令

条件转移指令,所有段条件转移指令都是短转移,对应的机器码中包含转移的位移而不是目的地址。

指令格式

jcxz  标号 (如果(cx)= 0, 转移到标号处执行)

操作  当 (cx)= 0,  (IP) = (IP)+ 8位位移

8位位移 = 标号处地址 - JCXZ指令后的第一个字节的地址

8位位移量范围-128~127,用补码表示

8位位移由编译器中编译时算出


当(CX)!=0 时 程序什么也不做

监测点9.2 查找从内存2000H段中第一个值位0段字节,找到后将他的偏移地址存储在dx中

;find the first address from segment 2000H ;with the value of the address equal to zeroassume cs:codecode segmentstart:mov ax, 2000hmov ds, axmov bx, 0s:mov cl, ds:[bx]mov ch, 0jcxz okinc bxjmp short sok:mov dx, bxmov ax, 4c00hint 21hcode endsend start


9.8 loop 指令

所有循环指令都是短转移,中对应机器码中包含转移的位移,而不是目的地址。

(cx)= (cx) - 1

如果  (cx) != 0 跳转至标号处  (IP)= (IP)+8位位移

8位位移 = 标号处地址 - loop指令后的第一个字节的地址

8位位移量范围-128~127,用补码表示

8位位移由编译器中编译时算出


loop的功能等于 if(cx != 0) jmp short 标号;


检测点9.3

使用loop 在内存2000H处查找第一个值位0的字节

;find the first address from segment 2000H ;with the value of the address equal to zeroassume cs:codecode segmentstart:mov ax, 2000hmov ds, axmov bx, 0s:mov cl, ds:[bx]mov ch, 0inc cxinc bxloop sok:dec bxmov dx, bxmov ax, 4c00hint 21hcode endsend start

 9.9 根据位移进行转移的意义

jmp short 标号

jmp near ptr 标号

jcxz 标号

loop 标号

为了方便程序段在内存中的浮动装配


9.10 编译器对转移位移超界对检测

以下代码编译会报错

assume cs:codecode segmentstart:jmp short sdb 255 dup (0)s: mov ax, 0ffffhcode endsend start

实验8

分析以下程序是否可以运行

assume cs:codesgcodesg segmentmov ax, 4c00hint 21hstart:mov ax, 0s:nopnopmov di, offset smov si, offset s2mov ax, cs:[si]mov cs:[di], axs0:jmp short ss1:mov ax, 0int 21hmov ax, 0s2: jmp short s1nopcodesg endsend start



可以看到,程序可以正常返回。利用来位移jmp最终程序跳转到开头的mov ax,4c00h  和  int 21h


实验9 根据实验材料编程在屏幕中央输出彩色字符


assume cs:code, ds:data, ss:stack;the data segment store the string and the color infodata segment;00hdb 'welcome to masm!';16 character;10hdb2h; bkColor = black, color = green (0 000 0 010B)db24h ; bkColor = green, color = red   (0 010 0 100B)db71h; bkColor = white, color = blue  (0 111 0 001B);13hdw5a0h ; map to the start 11th line position of the VRAM  5a0h + 40h;15hdw40h ; the offset position to write the first character of the linedata endsstack segmentdb 16 dup (0)stack endscode segmentstart:mov ax, data; map ds to data segmentmov ds, axmov ax, 0b800h; map es to vga ram segmentmov es, axmov ax, stack; map ss to stack segmentmov ss, axmov sp, 10h; init regmov cx, 3; write for three linemov bx, 0; for line numbermov bp, ds:[13h]; load the address fot vramadd bp, ds:[15h]; add the offset addresss:push cxmov cx, 16; write for 16 charactersmov si, 0; pointer to character arraymov di, 0; pointer to the target vrams0:mov al, ds: 00h[si]; read char to axmov ah, ds: 10h[bx]; read color infomov es:[bp][di], ax; store the char and color info to vraminc siadd di, 2loop s0add bp, 0a0h; point to the next lineinc bxpop cxloop smov ax, 4c00hint 21hcode endsend start





阅读全文
0 0
原创粉丝点击