X64指令基本格式


本文属于《 X86指令基础系列教程》之一,欢迎查看其它文章。

X64指令与X86指令兼容,因此不再对X86指令结构重复描述,主要以讲解X64上新特性为主。

1 REX Prefix结构

x64指令机器码,在原来X86 32位基础上,增加了Rex Prefix,如下所示:
在这里插入图片描述
AMD推出 x86 扩展 64 位技术时,增加了一个用于访问扩展的 64 位数据 prefix,它是:REX prefix,而 x86 原有的 prefix 则变为了指令格式中的:Legacy prefix

REX prefix 仅存在于 x64 的 64-bit 模式中,在 legacy x86 模式下,REX prefix 是无效的。 Legacy prefix在 x86 和x64下,均是有效的。

REX prefix 的取值范围是:40H - 4FH。在非 64 位模式下,它们是 inc 与 dec 指令;也就是说这些指令在 64 位模式下被重定义为 REX prefix,关于Prefix的介绍真的是少之又少,不过可以在x86/x64 指令编码内幕(适用于 AMD/Intel)学到很多。

这里就简单说一下吧,一个Legacy prefix还有一个REX prefix。这些修饰符是为了改变缺省的寄存器,比如说在32位下mov ax,bx。那么就要有Legacy prefix 0x66修饰,前者还有个作用就是改变当前段寄存器,不多这在目前已经显得不怎么重要了。

到了x64的时候,由于通用寄存器的扩展(主要原因),原本的8个通用寄存器只要3个位来标识,但是现在多了r8~r15,16个通用寄存器怎么办呢,很明显加上一位就能完全标识了。

那么就是REX prefix的作用,看一下这个家伙的结构:
在这里插入图片描述
各个位的含义,如下:
在这里插入图片描述
他有取值范围,前4位一定是4,后四位可选,W,R,X,B。

  • W位,标识改变默认操作数大小,比如现在x64有个汇编代码mov r8,r10。一般很多指令都是默认32位操作数的,只有在CS.L1&&CS.D0的时候才会是64位操作数(我没见过)。
    所以一般都要去改变默认操作数大小,那REX prefix就是0x48 (Inter手册上常说是 REX.W);
  • R位,用来扩展 ModRM.reg 域,000 ~ 111 —> 0 000 ~ 1 111 ,于是现在寄存器的情况变成了如下:
    在这里插入图片描述
  • X位,用来扩展 SIB.index 域;
  • B位,用来扩展 SIB.base, ModRM.r/m 以及 Opcode.reg。

2 REX prefix扩展位

REX prefix=0100WRXB,扩展位WRXB的使用场景,有以下4种。

2.1 第一种,无SIB字节的内存寻址(mod !=11 )

在这里插入图片描述
比如:mov rcx,[r8],机器码:49 8B 0B

  • 扩展ModRM.reg
    在X86 32位架构下,ModRM字节中reg有3位,可以表示eax、ebx、ecx、edx、esi、edi、ebp、esp共8个寄存器。
    但是,在X64架构下,有rax、rbx、rcx、rdx、rsi、rdi、rbp、rsp、r8、r9、r10、r11、r12、r13、r14、r15共16个寄存器,reg原有的3位不够用了,因此,需要与REX prefix中R位合并扩展为4位Rrrr,表示X64架构下这16个寄存器编号,具体编号如下:
r8(/r)
r16(/r)
r32(/r)
r64(/r)
mm(/r)
AL
AX
EAX
RAX
MM0
CL
CX
ECX
RCX
MM1
DL
DX
EDX
RDX
MM2
BL
BX
EBX
RBX
MM3
SPL
SP
ESP
RSP
MM4
BPL
BP
EBP
RBP
MM5
SIL
SI
ESI
RSI
MM6
DIL
DI
EDI
RDI
MM7
r8b
r8w
r8d
r8
r9b
r9w
r9d
r9
r10b
r10w
r10d
r10
r11b
r11w
r11d
r11
r12b
r12w
r12d
r12
r13b
r13w
r13d
r13
r14b
r14w
r14d
r14
r15b
r15w
r15d
r15
Rrrr0000000100100011010001010110011110001001101010111100110111101111
  • 扩展ModRM.r/m
    在X86 32位架构下,ModRM字节中r/m有3位,可以表示8种内存寻址方式。
    但是,在X64架构下,由于寄存器数量翻倍,原来的3位不足以表示所有寄存器的寻址方式,因此,需要与REX prefix中B位合并扩展为4位Bbbb,并且与X86 32位架构下一样,再次与ModRM.mod组合,表示64种内存寻址方式,如下所示:
    在这里插入图片描述
    在这里插入图片描述

2.2 第二种,寄存器到寄存器的寻址(无内存操作数,mod=11)

在这里插入图片描述
比如:mov r9,r8,机器码:4D 8B C8
ModRM.reg与ModRM.r/m的扩展与上文描述完全一致,不再赘述。

2.3 第三种,带SIB字节的内存寻址(mod!=11 & r/m=100)

在这里插入图片描述
比如:mov rax,[rbx+rcx*2],机器码:48 8B 04 4B

  • 扩展ModRM.reg
    ModRM.reg的扩展与上文描述完全一致,不再赘述。
  • 扩展SIB.index
    以下为32位时,SIB的寻址地址计算。
    在这里插入图片描述
    也是由于X64下,寄存器数量增加,index只有3位,只能表示8个寄存器。因此需要将REX.X与index合并为4位Xxxx,可以表示16个寄存器。Xxxx为X64架构下寄存器的编号。
  • 扩展SIB.base
    X64下,寄存器数量增加,base只有3位,只能表示8个寄存器。因此需要将REX.B与base合并为4位Bbbb,可以表示16个寄存器。Bbbb为X64架构下寄存器的编号。

2.4 第四种,寄存器操作数编码于操作码字节中

在这里插入图片描述
比如:mov rax,4,机器码:48 C7 C0 04 00 00 00
需要将REX.B与reg合并为4位Bbbb,可以表示16个寄存器。Bbbb为X64架构下寄存器的编号。

3 RIP寻址

X64架构的寻址模式与X86类似,但不完全等同,X64架构提供了一种新的rip相对寻址模式(RIP-Relative),引用单常量地址的指令,被编码为基于rip的偏移量(offsets)。
例如:

mov rax, [addr] 		;指令移动以addr+rip为起始地址的8字节内容到rax寄存器。

在64位模式下,RIP-Relative寻址,实现了一种新的寻址形式,rip相对(相对指令指针)寻址。有效的地址,是通过在下一条指令的64位RIP上增加位移来形成的。在IA-32体系结构和兼容模式下,相对于指令指针的寻址只适用于控制转移指令。

在64位模式下,使用ModR/M寻址的指令可以使用rip相对寻址。没有rip相对寻址,所有ModR/M指令模式都相对于零寻址内存。

RIP相对寻址允许特定的ModR/M模式使用带符号的32位位移来寻址相对于64位RIP的内存。这提供了与RIP的±2GB的偏移范围。rip相对寻址的ModR/M和SIB编码如下表所示。在当前的ModR/M和SIB编码中存在32位位移寻址的冗余形式。有一种ModR/M编码和几种SIB编码。rip相关寻址使用冗余形式进行编码。在64位模式下,ModR/M Disp32(32位位移)编码被重新定义为RIP+ Disp32,而不仅是位移。
在这里插入图片描述
rip相对寻址的ModR/M编码不依赖于使用前缀。具体来说,101B的r/m位域编码(用于选择rip相对寻址)不受REX前缀的影响。例如,选择“R13”(REX.B = 1, r/m = 101B)时,只要mod = 00B仍然会导致rip相对寻址。REX.B结合ModR/ m的4位r/m字段没有被完全解码。为了处理没有位移的R13,软件必须使用1字节的位移0对R13 + 0进行编码。

rip相对寻址由64位模式启用,而不是64位的address-size。使用address-size前缀不会禁用rip相对寻址。地址大小前缀的作用是截断并零扩展计算出的有效地址为32位。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
目录 第一篇 x86 基础 第1 章数与数据类型2 1.1 数 2 1.1.1 数字 2 1.1.2 二进制数 3 1.1.3 二进制数的排列 3 1.1.4 十六进制数 5 1.1.5 八进制数与十进制数 5 1.2 数据类型 6 1.2.1 integer 数 6 1.2.2 floating-point 数. 9 1.2.3 real number(实数)与NaN(not a number) . 11 1.2.4 unsupported 编码值 14 1.2.5 浮点数精度的转换 15 1.2.6 浮点数的溢出 17 1.2.7 BCD 码 20 1.2.8 SIMD 数据 21 第2 章 x86/x64 编程基础 23 2.1 选择编译器 23 2.2 机器语言 24 2.3 Hello world 25 2.3.1 使用寄存器传递参数 26 2.3.2 调用过程 27 2.3.3 定义变量 27 2.4 16 位编程、32 位编程,以及64 位编程 28 2.4.1 通用寄存器 28 2.4.2 操作数大小 30 2.4.2 64 位模式下的内存地址 30 2.4.4 内存寻址模式 31 2.4.5 内存寻址范围 34 2.4.6 使用的指令限制 34 2.5 编程基础 34 2.5.1 操作数寻址 35 2.5.2 传送数据指令 39 2.5.3 位操作指令 45 2.5.4 算术指令 47 2.5.5 CALL 与RET 指令 48 2.5.6 跳转指令 48 2.6 编辑与编译、运行 48 第 3 章编写本书的实验例子 50 3.1 实验的运行环境 50 3.2 生成空白的映像文件 52 3.2.1 使用nasm 编译器生成 52 3.2.2 使用bximage 工具 52 3.3 设置bochs 配置文件. 53 3.4 源代码的基本结构 54 3.5 编译源代码55 3.6 映像文件内的组织 55 3.7 使用merge 工具 56 3.7.1 merge 的配置文件 57 3.7.2 执行merge 命令 57 3.8 使用U 盘启动真实机器 58 3.8.1 使用merge 工具写U 盘 58 3.8.2 使用hex 编辑软件写U 盘 59 3.9 编写boot 代码 60 3.9.1 LBA 转换为CHS 62 3.9.2 测试是否支持int 13h 扩展功能 63 3.9.3 使用int 13h 扩展读磁盘 64 3.9.4 最后看看load_module() 64 3.10 总结 66 第4 章处理器的身份 67 4.1 测试是否支持CPUID 指令 67 4.2 CPUID 指令的术语及表达 68 4.3 基本信息与扩展信息 68 4.4 处理器的型号(family,model 与stepping) 72 4.5 最大的物理地址和线性地址 73 4.6 处理器扩展状态信息74 4.6.1 探测Processor Extended State 子叶 75 4.6.2 Processor Extended State 子叶所需内存size 76 4.6.3 Processor Extended State 的保存 77 4.6.4 Processor Extended State 的恢复 78 4.7 处理器的特性 78 4.8 处理器的Cache 与TLB 信息 80 4.9 MONITOR/MWAIT 信息 83 4.10 处理器的long mode 84 第 5 章了解 Flags 85 5.1 Eflags 中的状态标志位 86 5.1.1 signed 数的运算 86 5.1.2 unsigned 数的运算 89 5.2 IOPL 标志位 90 5.3 TF 标志与RF 标志 93 5.4 NT 标志 95 5.5 AC 标志 96 5.6 VM 标志 98 5.7 eflags 寄存器的其他事项 99 第 6 章处理器的控制寄存器 101 6.1 CR8 102 6.2 CR3 103 6.3 CR0 104 6.3.1 保护模式位PE 104 6.3.2 x87 FPU 单元的执行环境 104 6.3.3 CR0.PG 控制位 108 6.3.4 CR0.CD 与CR0.NW 控制位 108 6.3.5 CR0.WP 控制位 110 6.3.6 CR0.AM 控制位 110 6.4 CR4 110 6.4.1 CR4.TSD 与CR4.PCE 控制位 110 6.4.2 CR4.DE 与CR4.MCD 控制位 111 6.4.3 CR4.OSFXSR 控制位 111 6.4.4 CR4.VMXE 与CR4.SMXE 控制位 111 6.4.5 CR4.PCIDE 与CR4.SMEP 控制位 112 6.4.6 CR4.OSXSAVE 控制位 113 6.4.7 CR4 中关于页的控制位 113 6.5 EFER 扩展功能寄存器 114 第 7 章 MSR. 116 7.1 MSR 的使用 116 7.2 MTRR 117 7.2.1 Fixed-range 区域的映射 118 7.2.2 MTRR 的功能寄存器 120 7.3 MSR 中对特殊指令的支持 124 7.3.1 支持sysenter/sysexit 指令的MSR 125 7.3.2 支持syscall/sysret 指令的MSR 126 7.3.3 支持swapgs 指令的MSR 127 7.3.4 支持monitor/mwait 指令的MSR 128 7.4 提供processor feature 管理 129 7.5 其他未列出来的MSR 129 7.6 关于MSR 一些后续说明 129 第二篇 处理器的工作模式 第8 章实地址模式 132 8.1 真实的地址 132 8.2 real mode 的编址 132 8.3 real mode 的状态 133 8.4 段基址的计算 134 8.5 第1 条执行的指令 134 8.6 实模式下的执行环境 135 8.7 实模式下的IVT 135 8.8 突破64K 段限 136 8.9 A20 地址线 137 第 9 章 SMM系统管理模式探索 138 9.1 进入SMM 138 9.2 SMM 的运行环境 141 9.2.1 SMRAM 区域 141 9.2.2 SMM 执行环境的初始化 143 9.2.3 SMM 下的operand 与address 144 9.2.4 SMM 下的CS 与EIP 144 9.2.5 SMM 下的SS 与ESP 145 9.3 SMM 里的中断 145 9.4 SMI 的Back-to-Back 响应 147 9.5 SMM 里开启保护模式 147 9.6 SMM 的版本 148 9.7 I/O 指令的重启及Halt 重启 151 9.8 SMM 的退出 152 9.9 SMBASE 的重定位. 153 9.10 SMI 处理程序的初始化 154 9.11 SMM 的安全 156 9.11.1 芯片组的控制 156 9.11.2 处理器对SMRAM 空间的限制 158 9.11.3 cache 的限制 160 9.12 测试SMI 处理程序 161 第 10 章 x86/x64 保护模式体系(上) 163 10.1 x86/x64 的权限 164 10.2 保护模式下的环境 164 10.2.1 段式管理所使用的资源 165 10.2.2 paging 分页机制所使用的资源 165 10.3 物理地址的产生 166 10.4 段式管理机制 167 10.4.1 段式内存管理 168 10.4.2 段式的保护措施 168 10.5 段式管理的数据结构 169 10.5.1 Segment Selector(段选择子) 169 10.5.2 Descriptor Table(描述符表) 172 10.5.3 Segment Selector Register(段寄存器) 174 10.5.4 Segment Descriptor(段描述符) 175 10.5.5 LDT 描述符与LDT 258 10.6 开启保护模式 259 10.6.1 初始化GDT 260 10.6.2 初始化IDT. 262 10.6.3 切换到保护模式 263 第11 章 x86/x64 保护模式体系(下) 265 11.1 物理页面 265 11.1.1 处理器的最高物理地址(MAXPHYADDR) 266 11.1.2 物理页面的大小 267 11.1.3 页转换模式(Paging Mode) 268 11.2 paging 机制下使用的资源 270 11.2.1 寄存器 270 11.2.2 CPUID 查询leaf 270 11.2.3 寄存器的控制位 271 11.2.4 页转换表资源 272 11.3 32 位paging 模式(non-PAE 模式) 273 11.3.1 CR3 结构 274 11.3.2 32 位paging 模式下的PDE 结构 275 11.3.3 使用32 位paging 279 11.4 PAE paging 模式. 282 11.4.1 在Intel64 下的CR3 与PDPTE 寄存器 283 11.4.2 在AMD64 下的CR3 285 11.4.3 PAE paging 模式里的PDPTE 结构 286 11.4.4 PAE paging 模式里的PDE 结构 286 11.4.5 PAE paging 模式里的PTE 结构 288 11.4.6 使用和测试PAE paging 模式 288 11.4.7 使用和测试Execution Disable 功能 292 11.5 IA-32e pagi
数学画图是数学教学和研究中常用的一种工具。在计算机编程领域中,有许多可以用来进行数学画图的基本指令。 首先,数学画图的基本指令之一是确定坐标系。我们可以定义一个平面或者立体的坐标系来表示数据的位置。在二维平面上,我们通常使用直角坐标系,其中x轴和y轴垂直于彼此。在三维空间中,我们可以使用笛卡尔坐标系,其中x轴,y轴和z轴相互垂直。 其次,数学画图的基本指令之一是绘制点。我们可以通过给定的坐标,在图中标出一个点。通过指定点的横坐标和纵坐标,我们可以将点移动到所需的位置。 此外,数学画图的基本指令还包括绘制直线和曲线。我们可以通过给定两个或更多的点,连接它们以生成直线。同样,我们也可以通过给定一系列的点,绘制出曲线。 另外,数学画图的基本指令还包括绘制形状。我们可以绘制各种形状,如矩形、圆形、椭圆、三角形等。通过指定形状的参数,如长度、宽度、半径等,我们可以创建出所需的形状。 最后,数学画图的基本指令还包括设置颜色和样式。我们可以通过选择不同的颜色和样式,为图形添加视觉效果。例如,我们可以选择不同的线条颜色,填充颜色或阴影效果,使图形更加生动。 综上所述,数学画图的基本指令包括确定坐标系、绘制点、绘制直线和曲线、绘制形状以及设置颜色和样式。这些指令为我们提供了创建各种数学图形的基本工具,帮助我们更好地展示和理解数学概念。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

百里杨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值