x86指令集 字节大小

news/2024/12/16 22:28:56/文章来源:https://www.cnblogs.com/lsgxeva/p/18611249

x86指令集 字节大小

https://bbs.kanxue.com/thread-190127.htm

最近对x86_32架构下的许多程序进行了指令长度统计,结果表明所有程序所涉及的指令长度范围均为:1~11字节。
而根据INTEL 开发者手册上介绍的指令的最大长度限制为15字节。
但是,在什么情况或者架构上才会有12~15字节长度的指令呢?
还有,是否可以断定在X86_32架构下指令的最大长度为:11字节?如果是,有木有计算依据?

 

lock add dword ptr es:[eax+ecx*8+0x11223344], 0x12345678
在16 位模式下是15 bytes:
26 66 67 F0 81 84 C8 44 33 22 11 78 56 34 12

 

lock add dword ptr es:[eax+ecx*8+0x11223344], 0x12345678

仅仅在 16 位模式下,这条汇编语句的 encode 是 15 bytes

因为:它在 16 位模式下,需要进行 operand size override 和 address size override,因此能达到 prefix 的饱和

从而每个部分除了 opcode 外,都达到了饱和状态。刚刚好是 15 bytes:26 66 67 F0 81 84 C8 44 33 22 11 78 56 34 12

4 group 的 prefix 都使用上了,ModRM 和 SIB 都需要,displacement 和 immediate 都是 4 bytes 的,只有 opocde 是 1 byte

这条指令在 32 位是:26 F0 81 84 C8 44 33 22 11 78 56 34 12 (13 bytes)

在 64 位下:26 67 F0 81 84 C8 44 33 22 11 78 56 34 12 (14 bytes)

那是因为 32 位下缺省的 operands size 和 address size 是 32 位,不需要作 operand size override 和 address size override

在 64 位下缺省的 operands size 是 32 位,而 address size 是 64 位,因此不需要作 operand size override,但是需要做 address size override

 

disassembler 的反汇编的指令边界真实执行指令边界可能会不一致。当然造成这种不一样的人为的,实际上这是对 disassembler 的一种考验。

不要期望编译器会产生大于 15 bytes 的指令编码!除非它有错。不要认为 disassmbler(反汇编器)的结果就是真实执行指令结果,有可能会不一致!

现在:我们可以回答前面提到的三个疑问:

  • 真实的指令长度确实为 15 bytes
  • processor 会给我们保证这一点
  • 当加载超过 15 bytes 长度的指令时,processor 会给我们抛出 #GP 异常,它通过这种方式保证了 15 bytes 指令长度

 

x86指令集 :
16位,最大长度15字节
32位,最大长度13字节
64位,最大长度14字节

 

 

INSTRUCTION PREFIXES (前缀只有固定的这几个)
The instruction prefixes are divided into four groups, each with a set of allowable prefix codes:
• Lock and repeat prefixes.
— F0H—LOCK prefix.
— F2H—REPNE/REPNZ prefix (used only with string instructions).
— F3H—REP prefix (used only with string instructions).
— F3H—REPE/REPZ prefix (used only with string instructions).
• Segment override.
— 2EH—CS segment override prefix.
— 36H—SS segment override prefix
— 3EH—DS segment override prefix.
— 26H—ES segment override prefix.
— 64H—FS segment override prefix.
— 65H—GS segment override prefix.
• Operand-size override, 66H
• Address-size override, 67H
For each instruction, one prefix may be used from each of these groups and be placed in any
order. The effect of redundant prefixes (more than one prefix from a group) is undefined and may
vary from processor to processor.

 

 

32位

 

 

 

例2:随便找一个机器码如:FF 15 D4 81 DF 00

那么它的汇编语句是什么呢?

解码器会依次读入第 1 个字节,第 2 个字节等 ... 进行判断:

(1)第 1 个字节是什么? prefix 还是 opcode

(2)同样再判断第 2 个字节是不是 prefix,如果不是 prefix ,那么它就是 opcode 码

(3)如果第 2 个字节是 opcode 码,再判这个 opcode 需不需 ModRM 字节,如果需要,第 3 个字节就是 ModRM 字节

(4)根据 ModRM 字节判断需不需要 SIB 字节,第 4 个字节如果需它就是 SIB 字节

(5)判断 ModRM 字节是否需要 displacment 字节和 immediate 字节

根据上面的逻辑,得出:

FF:这个字节是个具有 Group 属性的 Opcode 码,它进行什么操作需要依赖于 ModRM 字节的 Reg 域。

换句话来说,FF 并不是完整独立的 Opcode 码,它要联合 ModRM 才能确定具体的操作。

15:这个是 ModRM 字节(mod-reg-r/m): ModRM.mod = 00,ModRM.reg = 010,ModRM.r/m = 101。

其中 ModRM.reg 域被 FF(opcode) 作为确定具体操作码的参考。

● Opcode + ModRm.reg : FF /010 最终确定为:Call 指令。

● ModRM.mod:00 表示操作数是 memory

● ModRM.r/m:这是一个 32 位的 displacement 值。

所以,这个机器码最终被解码为: call dword ptr [00DF81D4]

下面的直观的图表

 

下面来看看 x86/x64 指令 encode 的 2 个例子:

mov word ptr es:[eax + ecx * 8 + 0x11223344], 0x12345678

例子1:在当前 32 位系统下,有下面汇编语句(Intel 格式):

这是一条** mov** 指令,目标操作数是** memory**,源操作数是 immediate

注意:

我特地将目的操作数的大小定为是 word(2个字节),而不是 dword。但是,源操作数却是一个 dword 大小的 0x12345678。

那么:对于这条汇编语句,编译器应该如何处理呢?

  • 应该怎样处理 immediate 部分
  • 应该选择哪条 mov 指令
  • operand size 是多少
  • 在 32 位环境下,如何生成 16 位 operand 或 address 的代码
  • 寻址模式是什么

这些问题是我们最终需要掌握的知识,这是本栏目的最终目的。

实际上,它最终形成的机器编码是:26 66 c7 84 c8 44 33 22 11 78 56

(1)dword 大小的源操作数,会被编译器截断为 word 大小

(2)选择 MOV Ev, Iz 指令,它的 opcode 是 C7

(3)它的 operand size 是 word 大小,取决于 first operand 的 size

(4)在 32 位下,通过使用 operand size override 可以造型为 16 位 operands size,使用 address size override 可以造型为 16 位 address size

(5)它的寻址模式是:基址+变址寻址,它需要提供 SIB 字节

下面的图直观的分解这条指令的组成部分:

26:在指令序列里是:prefix 部分,它是 semgent overrride prefix ,作用是调整内存操作数的段选择子

66:在指令序列里是:prefix 部分,它是 operand size override prefix ,作用是调整操作数的缺省大小

C7:在指令序列里是:Opcode 部分,是 mov 指令是操作码

84:在指令序列里是:ModRM 值,定义操作数的属性

C8:在指令序列里:SIB 值定义内存操作数的属性

44332211:在指令序列里是: displacement 值

7856:在指令序列里是:immediate 值

这 2 个例子,作为对学习 x86/x64 指令编码的一个感性认识。

 

======== End

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/854010.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

实际项目中不一样的《桥接模式》

图片缩略图功能 需要对图片生产缩略图,压缩并保存到不同的介质中。输入端可能是本地图片,也可能是网络图片。保存的位置可能是本地,也有可能是第三方的minio、阿里云oss、七牛云oss。并且这些途径可能随时扩展。为了设计的灵活性,这里就要把输入可输出抽象出来,应用层通过…

一款渗透测试信息收集集成工具--mitan密探

本工具仅供安全测试人员运用于授权测试, 禁止用于未授权测试, 违者责任自负。作者及本公众号相关负责人不对您使用该工具所产生的任何后果负任何法律责任,在扫描模块使用多线程,在测试过程中根据目标的实际情况进行调整,切勿进行大线程低延时的大规模快速扫描,以免对目标服务…

最大网络流基本概念

1. 基本概念 1.1 流网络,不考虑反向边如果存在反向边也没事,不如有u->v和v->u两条边,那么就可以新加入一个点 p,u->v,v->p,p->u,转化为这三条边 1.2 可行流,不考虑反向边 1.2.1 两个条件:容量限制、流量守恒 容量限制:每条边流的不能超过这条边的权值 流量守…

sqli-labs

sqli-labs Less-1 基于错误的GET单引号字符型注入 index.php分析error_reporting(0); 不反馈错误 isset($_GET[id]) 检查($ _GET[id])参数是否设置 LIMIT 0,1 从第一条开始记录,只取一条记录1.推测闭合方式?id=1\输入\ ,后面是 ,推测是单引号闭合 输入 ?id=1 报错 输入 ?…

一文读懂:AI创业和投融资领域常见专有名词缩写详解

=== 预计悦读时间:3分钟 | 📚字数:约1000字——知识满满,不虚此行!🤔为什么你需要这篇神器? 就像由算法推荐给各位好奇的同学一样,我也被这些术语所困扰,想象一下,你正沉浸在一场关于AI的精彩演讲或者播客中,突然,一个神秘的英文缩写从嘉宾口中飞出,像是外星语言般让你瞬…

Simplex Method (单纯形方法)

学习目标:在本节中,我们将学习使用\(\textbf{单纯形法}\)解决线性规划最大化问题:(In this section, we will learn to solve linear programming maximization problems using the Simplex Method:)识别并建立标准的最大化形式的线性规划 (Identify and set up a linear pr…

《docker高级篇(大厂进阶):4.Docker网络》包括:是什么、常用基本命令、能干嘛、网络模式、docker平台架构图解

《docker高级篇(大厂进阶):4.Docker网络》包括:是什么、常用基本命令、能干嘛、网络模式、docker平台架构图解@目录二、高级篇(大厂进阶)4.Docker网络4.1Docker网络是什么4.2常用基本命令4.3能干嘛4.4网络模式4.4.1总体介绍4.4.2容器实例内默认网络IP生产规则4.4.3案例说明…

实验6 C++

任务四:Vector.hpp #pragma once #include <iostream> #include <stdexcept>using namespace std;template <typename T> class Vector { public:Vector(int n, int p = 0);Vector(const Vector<T> &v);~Vector();int get_size() const;T& a…

Docker安装Redis和Elasticsearch

本章将和大家分享在Docker中如何安装Redis和Elasticsearch。本章将和大家分享在Docker中如何安装Redis和Elasticsearch。废话不多说,下面我们直接进入主题。 一、Docker安装Redis 1、拉取最新版的 redis 镜像docker pull redis2、查看本地镜像docker images3、从官网获取 redi…

Redis应用—4.在库存里的应用

大纲 1.库存模块设计 2.库存缓存分片和渐进式同步方案 3.基于缓存分片的下单库存扣减方案 4.商品库存设置流程与异步落库的实现 6.库存入库时"缓存分片写入 + 渐进式写入 + 写入失败进行MQ补偿"的实现 7.库存扣减时"基于库存分片依次扣减 + 合并扣减 + 扣不了返…

Learn learn Cython

[SCTF ez_cython]简单分析需要调用一个cy库,找到文件"cy.cp38-win_amd64.pyd"pyd文件生成:编写pyx文件 \#test.pyx def say_hello_world(name): print("Hello world" % name)编写setup \#setup.py from distutils.core import setup from Cython.Build imp…

24.10.31 补充日志分析以及打包压缩

uniq 作用:去重,一般与sort搭配使用,单用uniq,是合并相邻两行相同内容 参数: -c #统计重复行的次数 eg:[root@oldboyedu ~]# cat uniq.txt oldboy lidao lidao lidao lidao oldboy oldboy lidao oldboy pldboy [root@oldboyedu ~]# uniq uniq.txt oldboy lidao oldboy l…