百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术分析 > 正文

理解Intel手册汇编指令 intel汇编语言程序设计

liebian365 2024-10-27 13:19 37 浏览 0 评论

指令格式





指令前缀:
分为4组,
每个前缀最多一个字节,一条指令最多4个前缀

  1. 第1组锁与重复(Lock and repeat)
    锁(LOCK)编码为:F0H。用于互斥访问共享内存的操作。
    非零时重复(REPNE/REPNZ)编码为:F2H。用于字符串操作指令。
    为零时重复(REP/REPE/REPZ)编码为:F3H。用于字符串操作指令。
  2. 第2组段覆盖与分支提示
    段覆盖(Segment override):CS、SS、DS、ES、FS、GS的段覆盖前缀的编码分别是2EH、36H、3EH、26H、64H、65H(在分支指令中使用未定义)。
    分支提示(Branch hints),只用于条件分支指令Jcc。提示分支不发生编码为2EH;提示分支发生编码为3EH。
  3. 第3组操作数长度覆盖(Operand-size override)编码为66H。用于在16位与32位操作数切换。例如,指令MOV ax, 1234H对应的十六机制机器码是"66 B8 34 12"(66即是操作数长度覆盖前缀)
  4. 第4组地址长度覆盖(Address-size override)编码为67H。用于在16位与32位地址切换。例如,指令MOV eax, [si]对应的十六进制机器码是"67 8B 04"(67即使地址长度覆盖前缀)

REX前缀:

REX前缀是64位模式下使用的指令前缀字节,如下作用:

  • 指定GPRs和SSE寄存器
  • 指定64位操作数大小
  • 指定扩展控制寄存器

并非所有指令在64位模式下都需要REX前缀。只有当指令引用扩展寄存器之一或使用64位操作数时,才需要前缀。如果REX前缀在没有任何意义的情况下使用,则会忽略它。每条指令只允许一个REX前缀。如果使用,REX前缀字节必须紧挨着操作码字节或转义操作码字节(0FH)。当REX前缀与包含强制前缀的指令一起使用时,强制前缀必须出现在REX之前,这样REX前缀就可以直接位于操作码或转义字节的前面。例如,带有REX前缀的CVTDQ2PD应该将REX放在F3和0F E6之间。其他位置被忽略。15字节的指令大小限制仍然适用于带有REX前缀的指令。

操作码(Opcode):

一个主操作码的长度可以是1、2或3个字节。一个额外的3位操作码字段有时被编码在ModR/M字节中。更小的字段可以在主操作码中定义。这些字段定义了操作方向、位移大小、寄存器编码、条件代码或符号扩展。一个操作码所使用的编码字段 操作码使用的编码字段根据操作的类别而不同。

ModR/M 和 SIB 字节:

许多在内存中引用操作数的指令在主操作码后面都有一个寻址形式的说明符字节(称为ModR/M字节)。ModR/M字节包含三个字段的信息:

  • mod字段与r/m字段结合形成32个可能的值:8个寄存器和24个寻址模式。
  • reg/opcode字段指定了一个寄存器编号或另外三个比特的操作码信息。reg/opcode字段的目的是在主操作码中指定的。
  • r/m字段可以将寄存器指定为操作数,也可以将其与mod字段组合起来对寻址模式进行编码。有时,mod字段和r/m字段的某些组合用于表示某些指令的操作码信息

某些编码的ModR/M字节需要第二个寻址字节(SIB字节)。32位寻址的基数加索引和比例加索引形式需要SIB字节。SIB字节包括以下字段:

  • scale字段指定缩放因子。
  • index字段指定索引寄存器的寄存器号。
  • base字段指定基寄存器的寄存器号

偏移和立即数字节:

有些寻址形式包括紧跟在ModR/M字节后面的位移(如果有的话,也可以是SIB字节)。如果需要一个位移,它可以是1、2或4个字节。

如果指令指定了立即操作数,则操作数总是紧跟在任何偏移字节之后。立即操作数可以是1、2或4个字节。


其他

  • 指令大小限制为不大于15字节。
  • 在64位模式下,使用RAX/RCX/RDX/RBX/RSP/RBP/RSI/RDI不需要REX Prefix,而使用R8 ~ R15则是必须的
  • 在Intel 64位架构指令集中的REX前缀(4xH)可以改变两类指令的长度:MOV指令的位移量和MOV指令的立即数。


操作模式

  • Intel保护模式(子模式:虚拟8086模式)
  • 实地址模式
  • 系统管理模式
  • IA-32e模式(子模式:兼容模式、64位模式)

内存模型

  • 平坦内存模型
  • 分段内存模型
  • 实模式内存模型

操作模式和内存模型关系


平坦内存

分段内存

实模式内存

Intel保护模式

Y

Y

Y

实地址模式

N

N

Y

系统管理模式

N

N

Y

兼容模式

Y

Y

Y

64位模式

Y

N

N



操作数

源操作数:

  • 立即数
  • 寄存器
  • 内存地址
  • I/O 端口

目的操作数:

  • 寄存器
  • 内存地址
  • I/O 端口


立即数:

MOV RAX,1122334455667788H

寄存器:


内存地址(内存有效地址):

Intel语法形式为 segreg:[base+index*scale+disp],而AT&T语法形式为 %segreg:disp(%base,%index,scale)


  • Displacement,单独的位移表示对操作数的直接(未计算的)偏移。因为位移是在指令中编码的,这种形式的地址有时被称为绝对或静态地址。它通常用于访问静态分配的标量操作数。(全局变量或静态变量)
  • Base,单独的基址代表操作数的间接偏移。由于基址寄存器中的值可以变化,它可以用于变量和数据结构的动态存储。(指针获取对应变量的值时)
  • Base + Displacement,基址寄存器加位移可以一起用于一下目的:
 1、当元素大小不是2、4或8字节时,作为一个数组的索引(位移组件编码到数组开始的静态偏移)基址寄存器保存了计算的结果来确定数组中某个特定元素的偏移量。
 2、要访问一个记录的某个字段:基址寄存器持有记录的起始地址,而位移是该字段的静态偏移。
 3、这种组合的一个重要特例是对程序函数中的参数的访问。在这里,EBP寄存器是基址寄存器的最佳选择。
  • (Index ? Scale) + Displacement,当元素大小为2、4或8字节时,这种地址模式提供了一种有效的方法来索引静态数组。位移定位到数组的开始,索引寄存器保存所需数组元素的下标,处理器通过应用缩放系数自动将下标转换为索引。
  • Base + Index + Displacement,同时使用两个寄存器可以支持二维数组(位移保存数组开头的地址)或记录数组的多个实例之一
  • Base + (Index ? Scale) + Displacement,当数组的元素大小为2、4或8字节时,使用所有寻址组件可以对二维数组进行有效的索引。
  • RIP相对寻址(64位独有的)rip 的名称来自于(instruction pointer register,指令指针寄存器)。rip其实就是程序计数器(Program Counter, PC), 存放着下一条指令的地址 。不可以直接修改rip。即rip + displacement的用法。
mov    [rip+0x202a62],rdi   //48 89 3D 62 2A 20 00


I/O端口:

每个外设都是通过读写其寄存器来控制的。外设寄存器也称为I/O端口,通常包括:控制寄存器、状态寄存器和数据寄存器三大类。

寄存器参与内存统一编址,访问寄存器就像访问一般的内存一样,所以,这种CPU没有专门用于设备I/O的指令。这就是所谓的“I/O内存”方式。另一类CPU,将外设的寄存器看成一个独立的地址空间,所以访问内存的指令不能用来访问这些寄存器,而要为对外设寄存器的读/写设置专用指令,如IN和OUT指令。这就是所谓的“ I/O端口”方式。

Intel支持以上两种方式。

// I/O端口
out 0x70, al
in al,0x70

MOV指令举例



//mov r/m8, r8
mov al, bh                                       //88 F8
mov byte ptr [ebx], al                     //67 88 03
//move r/m16, r16
mov bx, cx
mov word ptr [ebx], cx                   //67 66 89 0B
//selects MOV r/m64, imm32
mov qword ptr [rsp+08h], 0            //48 C7 44 24 08 00 00 00 00
mov rax,1122334455667788H        //48 B8 88 77 66 55 44 33 22 11
//selects MOV r/m32, imm32 
mov dword ptr [rsp+08h], 0            //C7 44 24 08 00 00 00 00
mov eax,11223344H                       //B8 44 33 22 11
mov rax, [1122334455667788H]     //48 A1 88 77 66 55 44 33 22 11
//mov moffs32*, eax
mov [11223344h],eax                     //A3 44 33 22 11 00 00 00 00
mov DS:[11223344h],eax               //A3 44 33 22 11 00 00 00 00
//mov eax, moffs32*
mov eax, [11223344h]                     //A1 44 33 22 11 00 00 00 00
mov eax, DS:[11223344h]               //A1 44 33 22 11 00 00 00 00
mov eax,[1122334455667788H]    //A1 88 77 66 55 44 33 22 11
//mov rax, moffs64*
//Direct Memory-Offset MOVs
mov rax,[1122334455667788H]     //48 A1 88 77 66 55 44 33 22 11


符号缩写说明:

  • Op/En(Operand Encoding
  • r/m (register or memory)
  • Sreg(segment register)
  • moffs(Direct Memory-Offset)

Opcode列:

cb, cw,

cd, cp,

co, ct

操作码后面的1字节(cb)、2字节(cw)、4字节(cd)、6字节(cp)、8字节(co)或10字节(ct)值。此值用于指定代码偏移量,也可能为代码段寄存器指定一个新值。

ib,

iw,

id, io

一个1字节(ib)、2字节(iw)、4字节(id)或8字节(io)的立即操作数,用于操作码、ModR/M字节或标度索引字节之后的指令。操作码决定了操作数是否为有符号的值。所有字、双字和四字都以小端字节序为先。

+rb,

+rw,

+rd,

+ro

表示操作码字节的低3位用于编码没有modR/M字节的寄存器操作数。

该指令列出了操作码字节低3位的相应十六进制值为000b。在非64位模式下,一个寄存器代码,从0到7,被添加到操作码字节的十六进制值中。在64位模式下,表示REX.b的4位字段和opcode[2:0]字段编码指令的寄存器操作数。"+ro "只适用于64位模式。

/r

表示指令的ModR/M字节包含一个寄存器操作数和一个r/m操作数。

/digit

0到7之间的数字表示指令的ModR/M字节只使用r/m(寄存器或内存)操作数。reg字段包含了为指令的操作码提供扩展的数字。

+i

当操作数之一是FPU寄存器堆的ST(i)时,浮点指令中使用的数字。数字i(范围从0到7)与加号左边给出的十六进制字节相加,形成一个操作码字节。

REX.W

表示使用了影响操作数或指令语义的REX前缀。请注意,将传统指令提升到64位行为的REX前缀并没有在操作码栏中明确列出。

NP

表示不允许使用66/F2/F3的前缀(超出指令操作码的一部分)。允许使用该指令。这样的使用将导致无效的操作码异常(#UD)或导致编码为不同的指令。


Instruction列:

rel8

rel8 — 从指令结束前的128字节到指令结束后的127字节范围内的一个相对地址。

rel16,

rel32

与指令装配在同一代码段内的相对地址。rel16 符号适用于操作数属性为16位的指令;rel32符号适用于操作数属性为32位的指令。

ptr16:16,

ptr16:32

一个远指针,通常指向与指令不同的代码段。符号16:16表示指针的值有两部分。冒号左边的值是一个16位的选择器或用于代码段寄存器的值。右边的值对应于目标段内的偏移。当指令的操作数属性为16位时使用ptr16:16符号;当操作数属性为32位时使用ptr16:32符号。

r8

单字节通用寄存器中的一个。AL、CL、DL、BL、AH、CH、DH、BH、BPL、SPL、DIL和SIL;或者使用REX.R和64位模式时可用的一个字节寄存器(R8L - R15L)。

r16

字通用寄存器中的一个。AX、CX、DX、BX、SP、BP、SI、DI;或使用REX.R和64位模式时可用的一个字寄存器(R8-R15)。

r32

双字通用寄存器中的一个。EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI;或在64位模式下使用REX.R时可用的一个双字寄存器(R8D - R15D)。

r64

四字的通用寄存器之一。RAX, RBX, RCX, RDX, RDI, RSI, RBP, RSP, R8-R15。这些在使用REX.R和64位模式时可用。

imm8

一个立即字节值。imm8符号是一个介于-128和+127之间的有符号数字。对于imm8与字或双字操作数结合的指令,立即值被代符号扩展为字或双字。字的上一个字节被填入立即值的最上面的位。

imm16

用于操作数属性为16位的指令的立即字值。这是一个介于-32,768和+32,767之间的数字。

imm32

用于操作数属性为32位的指令的立即双字值。它允许使用+2,147,483,647和-2,147,483,648之间的数字。

imm64

用于操作数属性为64位的指令的一个立即四字值。该值允许使用+9,223,372,036,854,775,807和-9,223,372,036,854,775,808之间的数字。

m

内存中的一个16位、32位或64位操作数。

m8

内存中的一个字节操作数,通常表示为一个变量或数组名称,但由DS:(E)SI或ES:(E)DI寄存器指向。在64位模式下,它由RSI或RDI寄存器指向。

m16

内存中的一个字操作数,通常表示为一个变量或数组名称,但由DS:(E)SI或ES:(E)DI寄存器指向。这个命名法只用于字符串指令。

m32

内存中的一个双字操作数,通常表示为一个变量或数组名称,但由DS:(E)SI或ES:(E)DI寄存器来指出。这个命名法只用于字符串指令。

m64

在内存中的一个内存四字操作数。

m128

在内存中的一个双四字操作数。

m16:16,

m16:32,

m16:64

一个内存操作数,包含一个由两个数字组成的远指针。冒号左边的数字对应于指针的段选择器。右边的数字与它的偏移量相对应。

m16&32,

m16&16,

m32&32,

m16&64

一个由数据项对组成的内存操作数,其大小在&符号的左边和右边表示。所有的内存寻址模式都被允许。m16&16和m32&32操作数被BOUND指令使用,提供一个包含数组索引的上下限的操作数。m16&32操作数被LIDT和LGDT用来提供一个字,用来加载极限字段,以及一个双字,用来加载相应的GDTR和IDTR寄存器的基字段。LIDT和LGDT在64位模式下使用m16&64操作数,以提供一个字来加载极限字段,以及一个四字来加载相应GDTR和IDTR寄存器的基字段。

moffs8,

moffs16,

moffs32,

moffs64

一个简单的内存变量(内存偏移),类型为字节、字或双字,用于MOV指令的一些变体。实际地址是由相对于段基的简单偏移量给出的。该指令中没有使用ModR/M字节。显示的moffs数字表示其大小,由指令的地址大小属性决定。

Sreg

一个分段寄存器。段寄存器的位分配是ES=0,CS=1,SS=2,DS=3,FS=4,GS=5。

m32fp,

m64fp,

m80fp

内存中的单精度、双精度和双扩展精度(分别)浮点操作数。这些符号指定浮点值,作为x87 FPU浮点指令的操作数。

m16int,

m32int,

m64int

内存中的一个字,双字和四字整数(分别)操作数。这些符号指定整数,作为x87 FPU整数指令的操作数。

ST or ST(0)

FPU寄存器堆栈的顶端元素。

ST(i)

从FPU寄存器堆栈的顶部开始的第i个元素(i ← 0到7)。

r/m8,

r/m16,

r/m32,

r/m64

寄存器或这内存。


参考

  • 《Intel? 64 and IA-32 Architectures Software Developer’s Manual》

相关推荐

4万多吨豪华游轮遇险 竟是因为这个原因……

(观察者网讯)4.7万吨豪华游轮搁浅,竟是因为油量太低?据观察者网此前报道,挪威游轮“维京天空”号上周六(23日)在挪威近海发生引擎故障搁浅。船上载有1300多人,其中28人受伤住院。经过数天的调...

“菜鸟黑客”必用兵器之“渗透测试篇二”

"菜鸟黑客"必用兵器之"渗透测试篇二"上篇文章主要针对伙伴们对"渗透测试"应该如何学习?"渗透测试"的基本流程?本篇文章继续上次的分享,接着介绍一下黑客们常用的渗透测试工具有哪些?以及用实验环境让大家...

科幻春晚丨《震动羽翼说“Hello”》两万年星间飞行,探测器对地球的最终告白

作者|藤井太洋译者|祝力新【编者按】2021年科幻春晚的最后一篇小说,来自大家喜爱的日本科幻作家藤井太洋。小说将视角放在一颗太空探测器上,延续了他一贯的浪漫风格。...

麦子陪你做作业(二):KEGG通路数据库的正确打开姿势

作者:麦子KEGG是通路数据库中最庞大的,涵盖基因组网络信息,主要注释基因的功能和调控关系。当我们选到了合适的候选分子,单变量研究也已做完,接着研究机制的时便可使用到它。你需要了解你的分子目前已有哪些...

知存科技王绍迪:突破存储墙瓶颈,详解存算一体架构优势

智东西(公众号:zhidxcom)编辑|韦世玮智东西6月5日消息,近日,在落幕不久的GTIC2021嵌入式AI创新峰会上,知存科技CEO王绍迪博士以《存算一体AI芯片:AIoT设备的算力新选择》...

每日新闻播报(September 14)_每日新闻播报英文

AnOscarstatuestandscoveredwithplasticduringpreparationsleadinguptothe87thAcademyAward...

香港新巴城巴开放实时到站数据 供科技界研发使用

中新网3月22日电据香港《明报》报道,香港特区政府致力推动智慧城市,鼓励公私营机构开放数据,以便科技界研发使用。香港运输署21日与新巴及城巴(两巴)公司签署谅解备忘录,两巴将于2019年第3季度,开...

5款不容错过的APP: Red Bull Alert,Flipagram,WifiMapper

本周有不少非常出色的app推出,鸵鸟电台做了一个小合集。亮相本周榜单的有WifiMapper's安卓版的app,其中包含了RedBull的一款新型闹钟,还有一款可爱的怪物主题益智游戏。一起来看看我...

Qt动画效果展示_qt显示图片

今天在这篇博文中,主要实践Qt动画,做一个实例来讲解Qt动画使用,其界面如下图所示(由于没有录制为gif动画图片,所以请各位下载查看效果):该程序使用应用程序单窗口,主窗口继承于QMainWindow...

如何从0到1设计实现一门自己的脚本语言

作者:dong...

三年级语文上册 仿写句子 需要的直接下载打印吧

描写秋天的好句好段1.秋天来了,山野变成了美丽的图画。苹果露出红红的脸庞,梨树挂起金黄的灯笼,高粱举起了燃烧的火把。大雁在天空一会儿写“人”字,一会儿写“一”字。2.花园里,菊花争奇斗艳,红的似火,粉...

C++|那些一看就很简洁、优雅、经典的小代码段

目录0等概率随机洗牌:1大小写转换2字符串复制...

二年级上册语文必考句子仿写,家长打印,孩子照着练

二年级上册语文必考句子仿写,家长打印,孩子照着练。具体如下:...

一年级语文上 句子专项练习(可打印)

...

亲自上阵!C++ 大佬深度“剧透”:C++26 将如何在代码生成上对抗 Rust?

...

取消回复欢迎 发表评论: