c - 汇编 如何将 IMUL 操作码(只有一个操作数)翻译成 C 代码

标签 c assembly x86 machine-code code-translation

说我有

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.

最佳答案

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 指令。

关于c - 汇编 如何将 IMUL 操作码(只有一个操作数)翻译成 C 代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7751491/

相关文章:

c - 我需要安装 glade gtkbuilder 和 gtk - x 的所有文件是什么

c - 将文件内容传递到内存时出现错误

c++ - 从 Linux 中的多个非阻塞命名管道读取

assembly - 如何为中断服务例程保存 x86_64 上的寄存器?

multithreading - AArch64 - 并行运行 ARM 和 ASIMD 指令

c - Arduino 端口重定位(PORTD 到 PORTB)

golang 进行意外的堆内存分配

assembly - 无法访问地址处的内存,缓冲区溢出尝试

linux - Cygwin:兼容性问题

linux - 使用 NASM 在 Assembly 中添加 2 个输入的数字