【问题标题】:Assembly How to translate IMUL opcode (with only one oprand) to C code汇编如何将 IMUL 操作码(只有一个操作数)转换为 C 代码
【发布时间】:2011-12-06 18:43:32
【问题描述】:

说我明白了

EDX = 0xA28

EAX = 0x0A280105

我运行这个 ASM 代码

IMUL EDX

据我了解,仅使用 EAX.. 如果指定了一个操作数

所以在 C 代码中应该是这样的

EAX *= EDX;

正确吗?

查看调试器后..我发现EDX 也被更改了。

0x0A280105 * 0xA28 = 0x67264A5AC8

在调试器中

EAX = 264A5AC8 EDX = 00000067

现在,如果您回答 0x67264A5AC8 并拆分第一个十六进制对,0x67 264A5AC8 您可以清楚地看到为什么 EDXEAX 是这样的。

好的,所以发生了溢出......因为它无法将这么大的数字存储到 32 位中。所以它开始在 EDX 中使用额外的 8 位

但我的问题是我现在如何在 C 代码中执行此操作以获得相同的结果?

我猜会是这样的

EAX *= EDX;
EDX = 0xFFFFFFFF - EAX; //blah not good with math manipulation like this.

【问题讨论】:

  • 该指令始终使用 EDX 来存储乘积,无论乘积值如何,结果是否可以无损失地表示为 32 位。

标签: c assembly x86 machine-code code-translation


【解决方案1】:

IMUL 指令实际上产生两倍于操作数大小的结果(除非您使用可以指定目标的较新版本之一)。所以:

imul 8bit -> result = ax, 16bits
imul 16bit -> result = dx:ax, 32bits
imul 32bit -> result = edx:eax, 64bits

在 C 中执行此操作将取决于编译器,但有些会这样做:

long result = (long) eax * (long) edx;
eax = result & 0xffffffff;
edx = result >> 32;

这假设 long 是 64 位。如果编译器没有 64 位数据类型,那么计算结果就会变得更加困难,你需要做长乘法。

你总是可以内联 imul 指令。

【讨论】:

  • 无法内联 imul 指令,我正在尝试将 ASM 实际模拟为 C 代码.. 所以寄存器会生成我.. CALL EAX's 这是我构建这个工具的唯一原因在不实际运行程序的情况下获取所有运行时调用
猜你喜欢
  • 2011-12-07
  • 2011-04-18
  • 2017-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-24
  • 2020-11-04
  • 1970-01-01
相关资源
最近更新 更多