汇编笔记_第九章

本文深入解析8086 CPU的转移指令,包括无条件转移、条件转移、循环指令等,详细说明jmp指令的不同类型及其实现方式,如段内短转移、段内近转移和段间转移。同时,介绍了如何通过位移进行转移,以及转移指令在内存和寄存器中的应用。

title: 汇编笔记_第九章
date: 2018-12-27 21:30:12

  • 笔记
    categories:
  • 汇编语言

转移指令的原理

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

  • 无条件转移指令(如:jmp
  • 条件转移指令
  • 循环指令(如:loop
  • 过程
  • 中断

操作符offset

offset的功能是 取得标号的偏移地址,是伪操作符;

assume cs:codesg
codesg segment
start:
mov ax,offset start ;相当于mov ax,0
s:
mov ax,offset s     ;相当于mov ax,3
codesg ends
end start

例题:

assume cs:codesg
codesg segment

start:
mov ax,bx   ;mov ax,bx的机器码占两个字节
mov si,offset start
mov di,offset s0

mov ax,cs:[si]
mov cs:[di],ax

s0:
nop         ;nop的机器码占一个字节
nop

codesg ends
end start

jmp指令

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

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

jmp short 标号(转到标号处执行指令)

  • 段内短转移
  • IP的修改范围为 -128~127

jmp short 标号的功能为:

  • (IP)=(IP)+8位位移;
  • 8位位移=“标号”处的地址-jmp指令后的第一个字节的地址;
  • short指明此处的位移位8位位移;
  • 8位位移的范围位-128~127,用补码表示;
  • 8位位移由编译程序在编译时算出;

CPU在执行jmp short 标号指令时只需知道转移的位移就行;

jmp near ptr 标号

实现 段内近转移,(IP)=(IP)+16位位移;

  • 16位位移=“标号”处的地址-jmp指令后的第一个字节的地址;
  • near ptr指明此处的位移位16位位移;
  • 16位位移的范围位-32769~32767,用补码表示;
  • 16位位移由编译程序在编译时算出

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

上面两个jmp指令相当于当前IP的转移位移;

jmp far ptr 标号实现的是 段间转移,又称远转移

  • (CS)=标号所在段的段地址;
  • (IP)=标号所在段中的偏移地址;
  • far ptr指明了指令用标号的段地址和偏移地址修改CS和IP;

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

指令格式:

jmp 16位寄存器

功能:IP=(16位寄存器);

转移指令在 内存 中的jmp指令

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

功能:从内存的单元地址处开始存放着一个字,事转移的目的偏移地址;

mov ax,0123h
mov ds:[0],ax
jmp word ptr ds;[0]

执行后(IP)=0123h

mov ax,0123h
mov [bx],ax
jmp word ptr [bx]

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

mov ax,0123h
mov ds:[0],ax
mov word ptr ds:[2],0
jmp dword ptr ds:[0]

执行后(CS)=0,(IP)=0123h,CS:IP指向0000:0123

mov ax,0123h
mov [bx],ax
mov word ptr [bx+2],0
jmp dword ptr[bx]

jcxz指令

  • jcxz指令位有条件转移指令;
  • 所有的有条件转移指令都是 短转移
  • 对应的机器码中包含转移的 位移,而不是目的地址,对IP的修改范围都为-128~127;
  • 指令格式: jcxz 标号,(如果(cx)=0,则转移到标号处执行);

例题:利用 jcxz 指令,实现在内存2000h段中查找第一个值为0的字节,找到后将偏移地址存储到dx中:

assume cs:code

code segment

start:
mov ax,2000h
mov ds,ax
mov bx,0

s:
mov ch,0
mov cl,ds:[bx]
jcxz ok
inc bx
jmp short s

ok:
mov dx,bx

mov ax,4c00h
int 21h

code ends
end start

loop指令

  • loop为循环指令;
  • 所有的循环指令都是短转移;

loop 标号:

  • (cx)=(cx)-1;
  • 如果 \((cx) \neq 0\),(IP)=(IP)+8位位移;
  • 8位位移=“标号”处的地址-loop指令后的第一个字节的地址;

例题:

;找到2000h段中第一个值为0的字节

assume cs:code
code segment
start:
mov ax,2000H
mob ds,ax
mov bx,0

s:
mov al,[bx]
mov ch,0
inc cx  ;若该字节为零,那么现在递增为1,之后的loop会使cx减一为零自动退出循环,
inc bx
loop s

ok:
dec bx      ;dec指令的功能和inc相反
mov dx,bx
mov ax,4c00h
int 21h

code ends
end start

根据位移进行转移的意义

jmp short 标号

jmp near ptr 标号

jcxz 标号

loop 标号

对IP的修改是根据转移目的地址和转移起始地址之间的 位移 来进行的,这样设计方便程序段在内存中的浮动装配;

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

原程序中出现转移范围超界的问题时,编译报错;
例如:

assume cs:code
code segment
start:
jmp short s
db 128 dup(0)
s:
mov ax,0ffffh
code ends
end start

jmp short s的转移范围为-128~127,IP最多向后移动127个字节;

但如果在debug中使用汇编指令jmp 2000:0100就没有问题,如果在源程序里使用也会报错;

https://www.cnblogs.com/31415926535x/p/10187942.html

(end)

转载于:https://www.cnblogs.com/31415926535x/p/10187942.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值