- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
作为一个小记忆,x86 架构将 0x0F 0x1F [mod R/M]
定义为多字节 NOP。
现在我正在研究 8 字节 NOP 的具体情况:我已经得到了
0x0F 0x1F 0x84 0x__ 0x__ 0x__ 0x__ 0x__
其中最后 5 个字节具有任意值。
第三个字节,[mod R/M]
,分割后给出:
mod = 10b
:参数为 reg1
+ DWORD 大小的位移reg2 = 000b
:(我们不在乎)reg1 = 100b
:表示参数是 SIB
字节 + DWORD 大小的位移。现在,作为一个具体的例子,如果我采取
0x0F 0x1F 0x84 0x12 0x34 0x56 0x78 0x9A
我有
SIB = 0x12
位移 = 0x9A785634
:一个 DWORD现在我添加 0x66
指令前缀来指示位移应该是 WORD 而不是 DWORD:
0x66 0x0F 0x1F 0x84 0x12 0x34 0x56 0x78 0x9A
我希望0x78 0x9A
被“切断”并被视为一条新指令。然而,当编译它并在生成的可执行文件上运行 objdump 时,它仍然使用所有 4 个字节(一个 DWORD)作为位移。
我是否误解了“位移”在这种情况下的含义?或者 0x66
前缀对多字节 NOP 指令没有任何影响?
最佳答案
66H
前缀将操作数的大小覆盖为 16 位。
如果您希望使用67H
,它不会覆盖地址的大小。 (但不要在 32 位代码中;这往往会导致 LCP stall ,特别是如果您使用 nopw [bx+0x1111]
与 disp16 而不是您从相同的 ModRM 编码,没有 67H
前缀。)
以下是所有传统 x86 前缀(不是 REX 或 VEX/EVEX)的列表。
F0h = LOCK -- locks memory reads/writes
String prefixes
F3h = REP, REPE
F2h = REPNE
Segment overrides
2Eh = CS
36h = SS
3Eh = DS
26h = ES
64h = FS
65h = GS
Operand override
66h. Changes size of data expected to 16-bit
Address override
67h. Changes size of address expected to 16-bit (in 32-bit mode)
<小时/>
但是,最好不要创建自己的 NOP 指令,而应遵循推荐的(多字节)NOP。
AMD 建议如下:
表 4-9。推荐的 NOP 指令多字节序列
bytes sequence encoding
1 90H NOP
2 66 90H 66 NOP
3 0F 1F 00H NOP DWORD ptr [EAX]
4 0F 1F 40 00H NOP DWORD ptr [EAX + 00H]
5 0F 1F 44 00 00H NOP DWORD ptr [EAX + EAX*1 + 00H]
6 66 0F 1F 44 00 00H NOP DWORD ptr [AX + AX*1 + 00H]
7 0F 1F 80 00 00 00 00H NOP DWORD ptr [EAX + 00000000H]
8 0F 1F 84 00 00 00 00 00H NOP DWORD ptr [AX + AX*1 + 00000000H]
9 66 0F 1F 84 00 00 00 00 00H NOP DWORD ptr [AX + AX*1 + 00000000H]
(此表中的反汇编是错误的:它在使用 66H
前缀的指令中显示 [AX]
。该前缀设置操作数-size 为 16,但地址大小未修改。如果在 32 位模式下使用 67H
前缀,则 AX 在 16 位寻址模式下不可编码。并且 16位地址大小意味着 2 字节位移而不是 4 字节,并且消除了 SIB 字节的可能性。这就是 67H
在 Intel CPU 上的 32 位模式下解码缓慢的部分原因,给出 false LCP stalls 。)
Intel 不介意最多 3 个冗余前缀,因此 nop 最多 11 个字节可以像这样构造。
10 66 66 0F 1F 84 00 00 00 00 00H NOP DWORD ptr [AX + AX*1 + 00000000H]
11 66 66 66 0F 1F 84 00 00 00 00 00H NOP DWORD ptr [AX + AX*1 + 00000000H]
<小时/>
您还可以通过在正常指令前添加冗余前缀来消除 NOP。例如
rep mov reg,reg //one extra byte
rep
通常被忽略,但新的 CPU 扩展经常使用 rep
使旧的操作码具有不同的含义。更安全的选择是前缀对于该操作码有效,但对寄存器操作数没有影响,就像段覆盖一样。或者像 DS
前缀(当它已经是默认值时),或者在 64 位模式下,其中 CS/DS/ES/SS 基数均为 0。
或者选择需要 REX 前缀的寄存器,因此汇编器必须使用同一指令的更长版本。
test r8d,r8d is one byte longer than: test edx,edx
带有立即操作数的指令有短版本和长版本(test
除外)。
and edx,7 //short imm8
and edx,0000007 //long imm32
大多数汇编器都会帮助您缩短所有指令,因此您必须使用 db
或 NASM/YASM 和 edx,严格 dword 7 自己编写较长的指令
。请参阅 What methods can be used to efficiently extend instruction length on modern x86? 了解更多有关此内容的一般信息。
将它们散布在战略位置可以帮助您对齐跳跃目标,而不必因 NOP 的解码或执行而产生延迟。
请记住,在大多数 CPU 上执行 NOP 仍然会消耗资源。前端解码/uop-cache/问题槽,并在 ROB 中跟踪它直到退役。填充其他指令会占用相同的额外 I-cache 空间,但不会产生其他成本。
当您为 Skylake 中 JCC 勘误的 Intel 微代码解决方法引入的性能缺陷启用解决方法时,这些扩展指令的技术有时会自动使用:请参阅 How can I mitigate the impact of the Intel jcc erratum on gcc?这可能需要扩展内部循环内的指令,而您确实不想在内部循环中使用 NOP,因此英特尔建议扩展早期的指令。
关于assembly - x86 多字节 NOP 和指令前缀,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27714524/
问题故障解决记录 -- Java RMI Connection refused to host: x.x.x.x .... 在学习JavaRMI时,我遇到了以下情况 问题原因:可
我正在玩 Rank-N-type 并尝试输入 x x .但我发现这两个函数可以以相同的方式输入,这很不直观。 f :: (forall a b. a -> b) -> c f x = x x g ::
这个问题已经有答案了: How do you compare two version Strings in Java? (31 个回答) 已关闭 8 年前。 有谁知道如何在Java中比较两个版本字符串
这个问题已经有答案了: How do the post increment (i++) and pre increment (++i) operators work in Java? (14 个回答)
下面是带有 -n 和 -r 选项的 netstat 命令的输出,其中目标字段显示压缩地址 (127.1/16)。我想知道 netstat 命令是否有任何方法或选项可以显示整个目标 IP (127.1.
我知道要证明 : (¬ ∀ x, p x) → (∃ x, ¬ p x) 证明是: theorem : (¬ ∀ x, p x) → (∃ x, ¬ p x) := begin intro n
x * x 如何通过将其存储在“auto 变量”中来更改?我认为它应该仍然是相同的,并且我的测试表明类型、大小和值显然都是相同的。 但即使 x * x == (xx = x * x) 也是错误的。什么
假设,我们这样表达: someIQueryable.Where(x => x.SomeBoolProperty) someIQueryable.Where(x => !x.SomeBoolProper
我有一个字符串 1234X5678 我使用这个正则表达式来匹配模式 .X|..X|X. 我得到了 34X 问题是为什么我没有得到 4X 或 X5? 为什么正则表达式选择执行第二种模式? 最佳答案 这里
我的一个 friend 在面试时遇到了这个问题 找到使该函数返回真值的 x 值 function f(x) { return (x++ !== x) && (x++ === x); } 面试官
这个问题在这里已经有了答案: 10年前关闭。 Possible Duplicate: Isn't it easier to work with foo when it is represented b
我是 android 的新手,我一直在练习开发一个针对 2.2 版本的应用程序,我需要帮助了解如何将我的应用程序扩展到其他版本,即 1.x、2.3.x、3 .x 和 4.x.x,以及一些针对屏幕分辨率
为什么案例 1 给我们 :error: TypeError: x is undefined on line... //case 1 var x; x.push(x); console.log(x);
代码优先: # CASE 01 def test1(x): x += x print x l = [100] test1(l) print l CASE01 输出: [100, 100
我正在努力温习我的大计算。如果我有将所有项目移至 'i' 2 个空格右侧的函数,我有一个如下所示的公式: (n -1) + (n - 2) + (n - 3) ... (n - n) 第一次迭代我必须
给定 IP 字符串(如 x.x.x.x/x),我如何或将如何计算 IP 的范围最常见的情况可能是 198.162.1.1/24但可以是任何东西,因为法律允许的任何东西。 我要带198.162.1.1/
在我作为初学者努力编写干净的 Javascript 代码时,我最近阅读了 this article当我偶然发现这一段时,关于 JavaScript 中的命名空间: The code at the ve
我正在编写一个脚本,我希望避免污染 DOM 的其余部分,它将是一个用于收集一些基本访问者分析数据的第 3 方脚本。 我通常使用以下内容创建一个伪“命名空间”: var x = x || {}; 我正在
我尝试运行我的test_container_services.py套件,但遇到了以下问题: docker.errors.APIError:500服务器错误:内部服务器错误(“ b'{” message
是否存在这两个 if 语句会产生不同结果的情况? if(x as X != null) { // Do something } if(x is X) { // Do something } 编
我是一名优秀的程序员,十分优秀!