首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >程序集:为什么某些x86操作码在x64中无效?

程序集:为什么某些x86操作码在x64中无效?
EN

Stack Overflow用户
提问于 2015-06-19 12:36:30
回答 2查看 2.1K关注 0票数 8

为什么在x64中某些操作码无效(例如0607 ),而在x86中则用于相当基本的指令(0607pushpop)?我认为这些最简单的指令在这两种架构中都会做得很好。

为什么他们在x64中禁用了一些简单的指令?为什么它们不起作用?当他们可以将操作码分配给x64版本的指令时,他们为什么会禁用一些操作码,在操作码列表中创建漏洞?

参考资料:

http://ref.x86asm.net/coder32.html

http://ref.x86asm.net/coder64.html

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-06-19 12:48:14

32位模式下的0607操作码是指令PUSH ESPOP ES.在64位模式下,段寄存器CS、DS、ES和SS不再用于确定内存地址:处理器的基址为0,没有大小限制。由于现在应用程序(操作系统本身除外)通常没有理由访问这些寄存器,因此删除了用于更改和访问这些寄存器的push/pop操作码,只留下了mov到/从Sreg (这只是两个总的操作码;寄存器号以ModRM字节而不是1字节操作码的一部分)。对于几乎从来不需要的东西来说,这是完全足够的。

FS和GS段寄存器仍然可以在64位模式下设置基本地址,因此与它们相关的push和pop操作码还没有被删除。(这些2字节0F xx操作码是在386中添加的,与旧的1字节操作码相比,对于8086段寄存器来说,它是一个不那么有价值的部分)。

然而,段寄存器的Push/pop或mov并不是OSes通常设置FS或GS段基的方式:这将需要GDT或LDT条目,并且只能在低32位内设置基。64位OSes将使用相关的MSR直接读取和写入基,而不是体系结构寄存器。(现代32位OSes也是这样做的,除非运行在不支持段基MSR的旧硬件上。)

票数 10
EN

Stack Overflow用户

发布于 2015-06-19 15:59:18

对于所有CPU,都有类似于“操作码空间”的东西。例如,如果一个CPU使用8位操作码,那么就会有一个最大值.它应该有256条指令。操作码越大,可以得到的操作代码就越多,但是快速获取和解码它们就越困难。

80x86是一个相对较老的体系结构。它开始于一个小的操作码空间,主要由1字节和2字节的操作码组成.每次CPU制造商添加新功能时,都会从操作码空间中获取更多的操作码。他们没有密码了。他们很快就跑出去了。

为了解决这个问题,他们开始做一些事情,比如添加转义码和前缀来人为地扩展操作码空间。例如,对于最近的AVX指令,您将看到一个VEX前缀,后面是一个旧的/回收转义代码(例如0xF0),后面是一个旧的/可回收的地址/操作数大小前缀(例如0x66),后面是另一个4个字节。不是很漂亮。

同时,现在很少使用的旧指令(AAD、AAM等)和具有多个/冗余操作码(INC/DEC)的指令正在消耗宝贵的“1字节”操作码。由于向后兼容性,这些不能/不能完全删除。

然而,当设计64位时,根本就没有任何64位代码可以兼容-向后兼容性并不重要。由“不太重要”的指令消耗的1字节操作码可以回收;使这些指令在64位代码中无效(但释放一些有价值的1字节操作码)。

这些1字节操作码中的大多数(如果我记得正确的话,整个1字节的INC/DEC组)立即被回收,用于支持64位操作数所需的REX前缀。有些是“将来的扩展是免费的”(限制是扩展只能在64位代码中工作,因为这些指令在16位和32位代码中仍然有效)。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30938318

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档