x86汇编指令

请注意:本文编写于 ,其中某些信息可能已经失去时效性。

前言

注:本文以 x86 指令集架构为例

数据传送指令

算数运算指令

逻辑运算指令

串指令

程序转移指令

可以修改 IP 或同时修改 CS 和 IP 寄存器内容的指令统称为转移指令。可以通俗理解为:转移指令就是可以控制 CPU 下一步执行内存中哪一处指令的指令。

在 8086 中按照转移行为可分为:

  1. 段内转移:只修改 IP
    1. 短转移:IP 修改范围为 -128~127(2^7-1)
    2. 近转移:IP 修改范围为 -32768~32767(2^15-1)
  2. 段间转移(远转移):同时修改 CS 和 IP

按照功能不同,转移指令又可细分为一下几种:

无条件转移指令

描述:无条件转移指令可以控制 CPU 下一步执行代码段(CS)中任意内存地址对应的指令

offset

描述

操作符,由编译器处理,功能是获取标号的偏移地址

实例
1
2
start: mov ax,offset start ; 相当于 mov ax,0
next: mov ax,offset next ; 相当于 mov ax,3 | 第一条指令长度为三个字节,因此 next 的偏移地址为 3

jmp

描述

转移地址可以在指令、内存或寄存器中指出。可以只修改 IP,也可以同时修改 CS 和 IP

用法

使用 jmp 指令时需要提供两种信息:

  1. 转移的目的地址
  2. 转移类型(段间转移(远转移)、段内短转移、段内近转移)
实例
  1. 转移目的地址在指令中

语法:jmp short 标号
作用:转移到标号处执行指令
描述:这种格式的 jmp 指令实现的是段内短转移,short 为短转移标志
原理:ip = ip + 8 位位移 | 8 位位移 = 标号地址 - jmp 指令后第一个字节的地址
此指令形式是针对当前指令所在位置(即当前 IP)进行跳转的,且 8 位位移范围是 -128~127,由编译程序在编译时计算
示例:

1
2
3
4
5
6
7
start:
mov ax,0
jmp short next
add ax,1
next:
inc ax
; 最终结果 ax 内的值为 1

语法:jmp near ptr 标号
作用:转移到标号处执行指令
描述:这种格式的 jmp 指令实现的是段内近转移,near 为近转移标志
原理:ip = ip + 16 位位移 | 16 位位移 = 标号地址 - jmp 指令后的第一个字节地址
此指令也是针对当前指令所在位置(即当前 IP)进行跳转的,且 16 位位移范围是 -32768~32767,由编译程序在编译时计算

语法:jmp far ptr 标号
作用:转移到标号处执行命令
描述:这种格式的 jmp 指令实现的是段间转移(即远转移),far ptr 为远转移标志
原理:cs = 标号所在段的段地址 | ip = 标号所在段中的偏移 | 高位存储段地址,低位存储偏移地址

  1. 转移目的地址在内存中

语法:jmp word ptr 内存单元地址
作用:转移到目标内存地址所存储的地址处执行指令
描述:这种格式的 jmp 指令实现的是段内转移,word ptr 是转移标志
原理:ip = 内存地址所存储的内容

语法:jmp dword ptr 内存单元地址
作用:在内存单元地址处存放两个字,高地址存放转移的目的段地址,低地址存放转移的目的偏移地址
描述:这种格式的 jmp 指令实现的是段间转移(即远转移),dword ptr 为远转移标志
原理:cs = 内存单元地址 + 2 所存储的内容 | ip = 内存单元地址存储的内容
示例:

1
2
3
4
5
mov ax,0123H
mov ds:[0],ax
mov word ptr ds:[2],0
jmp dword ptr ds:[0]
; 执行后 cs = 0 | ip = 0123H
  1. 转移目的地址在寄存器中

语法:jmp 16位寄存器
作用:转移到目标寄存器所存储的地址处执行指令
描述:这种格式的 jmp 指令实现的是段内转移
原理:ip = 16位寄存器内容

语法:jmp 段地址:偏移地址
作用:转移到目标地址处执行命令
描述:这种格式的 jmp 执行实现的是段间转移
原理:cs = 段地址 | ip = 偏移地址

条件转移指令

循环控制指令

终端指令

处理器控制指令

伪指令

处理器控制指令

参考

  1. Inno’s Blog:汇编语言学习笔记(九):转移指令的原理
  2. jasonM:一步步学习汇编(10)之jmp指令原理分析(破解软件的必修课)