9.《汇编语言》-王爽第三版学习笔记 转移指令的原理

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的修改是根据 转移目的地址和转移起始地址之间的位移来进行。在它们对应的机器码中不包含转移的目的地址,而包含的是目的地之的位移。方便了程序段在内存中的浮动装备,无论目的地址如何变化,指令的转移位移是不变的。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,132评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,802评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,566评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,858评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,867评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,695评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,064评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,705评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,915评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,677评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,796评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,432评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,041评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,992评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,223评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,185评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,535评论 2 343

推荐阅读更多精彩内容