9.《汇编语言》

您所在的位置:网站首页 loop指令结束条件 9.《汇编语言》

9.《汇编语言》

2024-07-12 03:18| 来源: 网络整理| 查看: 265

1.可以修改 IP, 或通知修改 CS 和 IP 的指令 统称为 转移指令。

概括的讲,转移指令就是可以控制 CPU 执行内存中某处代码的指令。

8086CPU 的转移行为有一下几类:

只修改 IP 时, 称为段内转移, 比如: jmp ax 同时修改 CS 和 IP 时,称为段间转移,比如: jmp 1000:0

由于转移指令对 IP 的修改范围不同,段内转移又分为: 短转移 和 近转移

短转移 IP 的修改范围为 -128~127 近转移 IP 的修改范围 -3287~32767

8086CPU 的转移指令分为以下几类:

无条件转移指令(如: jmp) 条件转移指令 循环指令(如:loop) 过程 中断 2. 操作符 offset

offset在汇编语言中是由编译器处理的符号。他的功能是 取得标号的偏移地址。

// 将 start 处的第一条指令 复制到 s0处: assume cs:codesg codesg segment start: mov ax,bx mov si,offset start // 相当于 mov si,0 mov di,offset s0 // 相当于 mov di, s0代码段的首地址 mov ax,cs:[si] mov cs:[di],ax s0: nop // nop的机器码占一个字节 nop mov ax,4c00H int 21H codesg ends end start 3. jmp 指令

jmp 指令 为 无条件转移指令,可以只修改 IP,也可以同时修改 CS 和 IP。需要给出两种信息: (1)转移的目的地址 (2)转移的距离(段间转移,段内短转移,段内近转移)

3. 依据位移进行转移的 jmp 指令

jmp short 标号 (转移到标号处执行指令) 这种格式的 jmp 指令实现的是 段内短转移,它对 IP 的修改范围为 -128~127,也就是说,它向前转移时最多越过 128 个字节,向后转移可以最多越过 127 个字节。 jmp指令中的"标号" 是 代码段中的标号, 指明了指令要转移的目的地,转移指令结束后, CS:IP 应该指向标号处的指令。

9B6875FF-4A69-419B-9720-5577A42FED9B.png

CPU在执行 jmp 指令的时候并不需要转移的目的地址。 ”jmp short 标号“ 指令所对应的机器码中,并不包含转移目的地的地址,而是包含转移的位移。这个位移 是编译器根据汇编指令中的 ”标号“ 计算出来的。

413F34DB-4766-4814-A820-4C86EEDEC68E.png

实际上 ”jmp short 标号“ 的功能为: (IP) = (IP)+8位位移 (1) 8位位移 = 标号处的地址 - jump 指令后第一个字节的地址 (2)short 指明此处的位移位 8位位移 (3)8位位移的范围为 -128~127,用补码表示。 (4)8位位移由编译程序在编译时算出。

实际上 ”jmp near ptr 标号“ 的功能为: (IP) = (IP)+16位位移 (1) 16位位移 = 标号处的地址 - jump 指令后第一个字节的地址 (2)near ptr 指明此处的位移位 16位位移, 进行的是段内近转移。 (3)16位位移的范围为 -32768~32787,用补码表示。 (4)16位位移由编译程序在编译时算出。

实际上 ”jmp far ptr 标号“ 的功能为: 段间转移,又称远转移 far ptr 指明了用 标号的段地址 和 偏移地址 修改 CS 和 IP。 (1) 16位位移 = 标号处的地址 - jump 指令后第一个字节的地址 (2)near ptr 指明此处的位移位 16位位移, 进行的是段内近转移。 (3)16位位移的范围为 -32768~32787,用补码表示。 (4)16位位移由编译程序在编译时算出。

F220E338-FF2C-4744-95DF-5CF4769EA72E.png

”jump16位 reg“ 的功能为: (IP)=(16位reg) far ptr 指明了用 标号的段地址 和 偏移地址 修改 CS 和 IP。 (1) 16位位移 = 标号处的地址 - jump 指令后第一个字节的地址 (2)near ptr 指明此处的位移位 16位位移, 进行的是段内近转移。 (3)16位位移的范围为 -32768~32787,用补码表示。

”jmp word ptr 内存单元地址“ 的功能为: 段内转移 从内存单元地址处开始存放着一个字,是转移的目的偏移地址。

”jmp dword ptr 内存单元地址“ 的功能为: 段间转移 从内存单元地址处开始存放着两个字,高地址处的字是转移的目的段地址, 低地址出是转移的目的偏移地址。 (CS)= (内存单元地址+2) (IP)=(内存单元地址)

4. 练习 1.若要使程序中的jmp指令执行后,CS:IP指向程序的第一条指令,在data段中应该定义哪些数据? assume ds:data,cs:code data segment db 2 dup (0) data ends code segment start: mov ax,data mov ds,ax mov bx,0 jmp word ptr [bx+1] mov ax,4c00h int 21h code ends end start 2.补全程序,使得jmp指令执行后,CS:IP指向第一条指令 assume ds:data,cs:code data segment dd 12345678H data ends code segment start: mov ax,data mov ds,ax mov bx,0 mov [bx],bx mov [bx+2],code jmp dword ptr ds:[0] mov ax,4c00h int 21h code ends end start 3.;内存数据如下 2000:1000 BE 00 06 00 00 00 …… 此时CPU执行指令 mov ax, 2000H mov es, ax jmp dword ptr es:[1000H] 后,(CS) = 0006H (IP) = 00BEH 5. jcxz 指令

指令格式: jcxz 标号 (如果 (cx)=0, 转移到标号处执行) (1)操作: 当(cx)= 0 时,(IP)=(IP)+ 8位位移 (2)8位位移=标号处的地址-jcxz指令后的第一个字节的地址 (3)8位位移的范围为 -128~127,用补码表示 (4)8位位移由编译程序在编译时算出。

当 (cx)!= 0 时,什么也不做,程序继续执行 jcxz 标号 = if (cx) == 0 jump short 标号 6. 练习

补全编程,利用jcxz指令,实现在内存2000H段中查找第一个值为0的字节,找到后,将它的偏移地址存储在dx中。

assume cs:code code segment start: mov ax,2000H mov ds,ax mov bx,0 s: mov cl,[bx] mov ch,0 jcxz ok inc bx jmp short s ok: mov dx,bx mov ax,4c00h int 21h code ends end start 7. loop 指令

指令格式:loop 标号 操作: (1)(cx)= (cx)+ 1 (2)如果(cx)!= 0, (IP)=(IP)+8 位位移

8. 练习

补全编程,利用loop指令,实现在内存2000H段中查找第一个值为0的字节,找到后,将它的偏移地址存储在dx中。

assume cs:code code segment start: mov ax,2000H mov ds,ax mov bx,0 s: mov cl,[bx] mov ch,0 inc cx inc bx loop s ok: dec bx mov dx,bx mov ax,4c00h int 21h code ends end start 9. 根据位移进行转移的意义

jmp short 标号 jmp near ptr 标号 jcxz 标号 loop 标号 他们对IP的修改是根据 转移目的地址和转移起始地址之间的位移来进行。在它们对应的机器码中不包含转移的目的地址,而包含的是目的地之的位移。方便了程序段在内存中的浮动装备,无论目的地址如何变化,指令的转移位移是不变的。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3