经典变长指令ModR/M
变长指令
不是所有的指令都是,看到opcode就知道有多长(定长指令),当指令中出现内存操作对象的时候,就需要在操作码后面附加一个字节来进行补充说明,这个字节被称为ModR/M。
该字节的8个位被分成了三部分:
其中,Reg/Opcode(第3、4、5位,共3个字节)描述指令中的G部分,即寄存器
Mod(第6、7位)和R/M(第0、1、2位)共同描述指令中的E部分,即寄存器/内存
因特尔白皮书:
MOV变长指令
0x88 MOV Eb, Gb G:通用寄存器
0x89 MOV Ev, Gv E:寄存器/内存
0x8A MOV Gb, Eb b:字节
0x8B MOV Gv, Ev v:Word, doubleword or quadword(这个看操作系统,是多少位就多少位)
0x88
0x88 01
MOV Eb, Gb: Gb决定了是8位的通用寄存器,具体是哪一个通用寄存器还要看ModR/M的3,4,5部分
01:00 000 001
前两位是Mod ;3,4,5位是Reg/Opcode;0,1,2位是R/M
由上面可以知道 Reg/Opcode部分是 000,相当于0号寄存器,即[EAX],但是由于是8位,所以是AL
012位和67位组合起来是00 001
是[ECX],所以这条指令应该是:mov byte ptr ds:[ECX],AL
0x88 15
MOV Eb, Gb: Gb决定了是8位的通用寄存器,具体是哪一个通用寄存器还要看ModR/M的3,4,5部分
01:00 010 101
前两位是Mod ;3,4,5位是Reg/Opcode;0,1,2位是R/M
由上面可以知道 Reg/Opcode部分是 001,相当于2号寄存器,即[ECX],但是由于是8位,所以是CL
012位和67位组合起来是00 101
可以看到这里并不是我们想的EBP,这是因为EBP指向栈底,而[EBP]通常存储上一个EBP,所以[EBP]无数据操作意义,Inter将这个编码废弃,改为立即数寻址
例如当操作指令为88 81 12 34 56 78时,其对应的汇编为MOV BYTE PTR DS:[ECX+78563412],AL
disp32实际上是个偏移
再看这几个 ESP都没有对应的值
这是因为:ESP指向栈顶,是浮动的,不确定的,Inter将这个编码废弃,由另外的格式来说明。
还是看一下
0x89
0x89 03
MOV Ev, Gv : Gv与我当前的x32dedug决定了是32位的通用寄存器,具体是哪一个通用寄存器还要看ModR/M的3,4,5部分
01:00 000 011
前两位是Mod ;3,4,5位是Reg/Opcode;0,1,2位是R/M
由上面可以知道 Reg/Opcode部分是 000,相当于0号寄存器,即EAX
012位和67位组合起来是00 011
所以是[EBX],这条指令是:mov dword ptr ds:[ebx],eax
这里只列举一个,这个指令与0x88区别就是位数的差别
0x8A
0x8A 07
MOV Gb, Eb: Gb决定了是8位的通用寄存器,具体是哪一个通用寄存器还要看ModR/M的3,4,5部分
01:00 000 111
前两位是Mod ;3,4,5位是Reg/Opcode;0,1,2位是R/M
由上面可以知道 Reg/Opcode部分是 000,相当于0号寄存器,即EAX,但我们这里是byte所以是al
012位和67位组合起来是00 111
是EDI,这条指令命令为:mov al,byte ptr ds:[edi]
0x8B
0x8B 26
MOV Gv, Ev : Gv与我当前的x32dedug决定了是32位的通用寄存器,具体是哪一个通用寄存器还要看ModR/M的3,4,5部分
01:00 100 110
前两位是Mod ;3,4,5位是Reg/Opcode;0,1,2位是R/M
由上面可以知道 Reg/Opcode部分是 100,相当于5号寄存器,即ESP
012位和67位组合起来是00 110
esi,mov esp,dword ptr ds:[esi]
0x8B 66 12
MOV Gv, Ev : Gv与我当前的x32dedug决定了是32位的通用寄存器,具体是哪一个通用寄存器还要看ModR/M的3,4,5部分
01:01 100 110
前两位是Mod ;3,4,5位是Reg/Opcode;0,1,2位是R/M
由上面可以知道 Reg/Opcode部分是 100,相当于5号寄存器,即ESP
012位和67位组合起来是01 110
[esi+12],mov esp.dword ptr ds:[esi+12]
总结
当Mod = 00时,ModR/M字节通过寄存器直接进行内存寻址
当Mod = 01时,ModR/M字节通过寄存器+I8进行内存寻址(I为立即数,即8位立即数)
当Mod = 10时,ModR/M字节通过寄存器+I32进行内存寻址
当Mod = 11时,ModR/M字节直接操作两个寄存器
经典变长指令ModR/M的更多相关文章
- 经典变长指令SIB
前言 ModR/M字段是用来进行内存寻址的,可当地址形如DS:[EAX + ECX*2 + 12345678]时,仅仅靠ModR/M字段,是描述不出来的. 这时就在ModR/M后面增加一个SIB字节, ...
- 经典变长指令-ModRM
一.如何计算ModRM 0X88 MOV Eb,Gb G:通用寄存器 0X89 MOV Ev,Gv E:寄存器/内存 0X8A MOV Gb,Eb b:字节 0X8B MOV Gv,Ev v:Word ...
- 经典变长指令-RegOpcode
一.回顾Mod/M结构 Intel 64 and IA-32 Architectures Instruction Format ModR/M结构图 Mod与R/M共同描述E的意义(内存或者通用寄存器) ...
- 经典定长指令-修改EIP
1.0x70~0x7F EIP无法像通用寄存器那样用mov来修改,只能通过类似于jz,JNB,JNE JBE,call等的跳转指令来进行修改 条件跳转,后跟一个字节立即数的偏移(有符号),共两个字节. ...
- C++中的变长参数
新参与的项目中,为了使用共享内存和自定义内存池,我们自己定义了MemNew函数,且在函数内部对于非pod类型自动执行构造函数.在需要的地方调用自定义的MemNew函数.这样就带来一个问题,使用stl的 ...
- C++内存分配及变长数组的动态分配
//------------------------------------------------------------------------------------------------ 第 ...
- (一)预定义宏、__func__、_Pragma、变长参数宏定义以及__VA_ARGS__
作为第一篇,首先要说一下C++11与C99的兼容性. C++11将 对以下这些C99特性的支持 都纳入新标准中: 1) C99中的预定义宏 2) __func__预定义标识符 3) _Pragma操作 ...
- CSAPP阅读笔记-变长栈帧,缓冲区溢出攻击-来自第三章3.10的笔记-P192-P204
一.几个关于指针的小知识点: 1. malloc是在堆上动态分配内存,返回的是void *,使用时会配合显式/隐式类型转换,用完后需要用free手动释放. alloca是标准库函数,可以在栈上分配任 ...
- Scala 变长参数
如果Scala定义变长参数 def sum(i Int*), 那么调用sum时,可以直接输入sum(1,2,3,4,5) 但是不可以sum(1 to 5) 必须要将1 to 5 强制为seq sum( ...
随机推荐
- Inspect Network Activity In Chrome DevTools
Inspect Network Activity In Chrome DevTools https://developers.google.com/web/tools/chrome-devtools/ ...
- USDN代币发行 关于USDN代币
"稳定币"是数字货币的一种,但与主流币存在的差异是,它可以通过锚定法币和加密资产等手段来维持币价的相对稳定.提及稳定币,一般会先介绍三种模式: 法币托管模式.数字资产抵押模式和无抵 ...
- NGK公链:夯实基础设施 实现产业大规模应用
当前,区块链已经成为全球技术角逐的前沿,大国及科技巨头竞相在该领域布局,引导区块链服务实体经济,激发市场经济活力.据市场相关研究机构预测,2020年,基于区块链的业务将达到1000亿美元. 对于区块链 ...
- 人物传记Daniel Bolsonaro:永远不要做一个思维单一的人
从小经历了移民和不断辗转迁徙搬家的Daniel Bolsonaro(现就职于灵石团队,职位是核心技术架构师)知道,人生不可能只有一条路,也不要局限于只给自己设立一条路.既然父母能带自己离开巴西来到美国 ...
- C++算法代码——扫雷游戏
题目来自:http://218.5.5.242:9018/JudgeOnline/problem.php?id=1685 题目描述 扫雷游戏是一款十分经典的单机小游戏. 在 n 行 m 列的雷区中有一 ...
- Java自学第10期——File类与IO流(输入输出流、处理流、转换流、缓冲流、Properties集合、打印流)
1.IO简介 IO(输入输出)通过java.io包下的类和接口来支持,包下包括输入.输出两种IO流,每种输入输出流又可分为字符流和字节流两大类. 2.File类 File类是io包下与平台无关的文件和 ...
- 第49天学习打卡(CSS 层次选择器 结构伪类选择器 属性选择器 美化网页元素 盒子模型)
推荐书籍:码出高效: Java 开发手册 2.2 层次选择器 idea里代码规范是按:ctrl +alt+L快捷键 注释快捷键:ctrl+/ 1.后代选择器:在某个元素的后面 祖爷爷 爷爷 爸爸 你 ...
- 看完我的笔记不懂也会懂----git
Git学习笔记 - 什么是Git - 首次使用Git - DOS常用命令 - Git常用命令 - 关于HEAD - 版本回退 - 工作区.暂存区与版本库 - git追踪的是修改而非文件本身 - 撤销修 ...
- vue3中使用axios如何去请求数据
在vue2中一般放在created中,但是在vue3中取消了created生命周期,请求方式有两种 直接在setup中去获取数据 setup(props) { const data = reactiv ...
- 原始提货单OBL
转: 原始提货单OBL 什么是原始提货单OBL? 原始提货单Original Bill of Lading,简称OBL.是货运单据或运输合同,可作为货物标题和装运收据.该文件确认承运人已收到货物.签发 ...