x86 操作码编码中的方向/符号扩展位

发布于 2024-11-27 18:43:04 字数 663 浏览 2 评论 0原文

在 x86 指令集中,操作码索引 1 处的位可以是指定目标操作数和源操作数的方向位,也可以是符号扩展位。

例如 add

  • 00 /r ADD r/m8 , r802 /r ADD r8, r/m8
    对于相同的助记符
  • 81 /0 id ADD r/m32, imm32, 该位区分 r/m, regreg, r/m83 /0 ib ADD r/m32, imm8
    完整(位 1 清除)与符号扩展立即数(位 1 设置)

我想知道确定这属于哪种情况的最简单的逻辑方法是什么。除了检查指令操作码并比较它们以找出它是什么(对于指令的符号扩展或方向位变体)之外,还有其他方法可以检查吗?还有一些指令忽略该位,但由于它被设置为 0,所以它并不重要。

编辑:事实证明,对于写错误(这就是我的代码的目的), reg->r/m 始终是这种情况,因为 ar/m->reg 指令永远不会触发写错误。但如果其他人遇到类似的问题,任何信息仍然会很好。

In the x86 instruction set the the bit at index 1 of an opcode can either be the direction bit which specifies what the destination and source operands are or it can be a sign extend bit.

e.g. for add

  • 00 /r ADD r/m8, r8 versus 02 /r ADD r8, r/m8
    That bit distinguishes r/m, reg vs. reg, r/m for the same mnemonic
  • 81 /0 id ADD r/m32, imm32 versus 83 /0 ib ADD r/m32, imm8
    full (bit 1 cleared) vs. sign-extended immediate (bit 1 set)

I'm wondering what's the easiest logical way to determine which of these cases it is. Is there a way to check other than checking the instruction opcodes and comparing them to find out which it is (for the sign extend or direction bit variants of the instructions)? There are also instructions that disregard this bit but since it's set to 0 then it doesn't really matter.

EDIT: Turns out that for write faults (which is what my code was intended for), reg->r/m is always the case because a r/m->reg instruction will never trigger a write fault. But any information would still be nice in case someone else is running into a similar issue.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

以往的大感动 2024-12-04 18:43:05

方向和符号位是 x86 处理器标志寄存器的一部分。由于标志的最低八位与 8080/8085/Z80 的标志具有相同的布局,我的猜测是索引 1 处的位是有符号位。如果我没记错的话,自 70 年代末 8086/88 处理器引入方向位以来,方向位的位置一直没有改变。

符号位位作为算术运算的结果而被修改,并且是运算结果的最高位的副本。 INC 和DEC 不影响符号位。

方向位使用 cld/std 指令进行操作,并控制块指令(cmps、ins、lods、movs、outs、scas 和 stos)是否后递增/递减。

它们也可以通过堆栈进行操作(尽管这对于符号位可能没有意义)

pushf
and dword ptr [esp],SOME_MASK
popf

使用“and”是一个示例:也可以使用 or、xor 等。

如果您操作该标志,您可能必须将其恢复到以前的值,因为某些运行时库假设它没有被修改。

The direction and sign bits are part of the flags register of the x86 processors. Since the lowest eight bits of the flags have the same layout as the flags of the 8080/8085/Z80 my guess is that the bit at index 1 is the signed bit. The position of the direction bit has not changed since it was introduced with the 8086/88 processors in the late 70s if my memory serves me.

The sign bit bit is modified as a result of an arithmetic operation and is a copy of the highest bit of the operation's result. INC and and DEC do not affect the sign bit.

The direction bit is manipulated using the cld/std instruction and controls whether the block instructions (cmps, ins, lods, movs, outs, scas and stos) post-increment/-decrement.

They may also be manipulated via the stack (though this is perhaps not meaningful with the sign bit)

pushf
and dword ptr [esp],SOME_MASK
popf

Using "and" is an example: or, xor and others may also be used.

If you manipulate the flag you may have to restore it to its previous value as some run-time libraries assume that it isn't modified.

生死何惧 2024-12-04 18:43:04

[评论已成为答案]。

显然,您需要一个针对指令字节流的布尔公式。我不知道如何轻松定义该公式; x86 的指令集非常混乱。我希望关键技巧是在由​​前缀字节确定的表中查找操作码字节。如果您正在编写某种反汇编程序,我希望您已经拥有这样的表。

[Comment made into answer].

You obviously need a boolean formula over the stream of instruction bytes. I wouldn't know how to define that formula easily; the x86 has a really messy instruction set. I'd expect the key trick is to lookup the opcode byte in a table determined by the prefix bytes. If you are writing some kind of disassembler, I'd expect you to have such tables already anyway.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文