Nasm-乘以2的值时的结果很奇怪

编辑:我使用this计算器检查结果,但是看来计算器本身在计算错误的值,从而导致了这个问题。

使用mul指令时,我注意到将2个高数字相乘会导致错误的值。例子:

mov eax,0ffffffffh
mov ebx,0ffffffffh
mul ebx
; eax:00000001 I expected eax to be 0
; edx:FFFFFFFE

mov eax,0ffffff00h
mov ebx,0ffffffffh
mul ebx
; eax:00000100 I expected eax also to be 0
; edx:FFFFFEFF

我知道-1 * -11,而ffffffffh是负1。但是,将这两个数字以无符号乘法相乘不会得到1,或者会吗?另一个示例也是如此。

同样,在使用imul指令时,我也会得到奇数,但是我认为这是因为有符号乘法:

mov eax,0fffffff0h
mov ebx,5
imul ebx
; eax:FFFFFFB0
; edx:FFFFFFFF ; I expected edx to be 4
qq252887487 回答:Nasm-乘以2的值时的结果很奇怪

您的结果正常,您的期望是错误的。 IDK是您产生错误期望的地方,但32位mul的64位结果在EDX:EAX中出现。

原来是来自在线计算器,它大概使用了Javascript编号,即具有53位尾数的double精度浮点,会将0xfffffffe00000001舍入到最接近的可表示双精度数,即{ {1}}。

对于带符号的情况,您使用的计算器完全错误,希望它将您的输入解释为32位2的补码。


乘法结果的下半部分不取决于您是否将输入解释为有符号,因此,作为快捷方式,我们可以使用0xfffffffe00000000在此处获得下半部分。 (这就是为什么英特尔只为-1 * -1 = 1,例如imul添加有效的非扩展表格的原因。

如果我们只是简单地在calc(在Ubuntu中打包为imul eax,edx,-1,在Arch中打包为apcalc)这样的扩展精度计算器中进行尝试:

calc

因此,这确认了CPU的结果。请记住,奇数乘以奇数就是一个奇数,因此也可以排除; base2(16) // ask for hex output as well as decimal ; 0x0ffffffff ^ 2 18446744065119617025 /* 0xfffffffe00000001 */ ; 0x0ffffff00 * 0x0ffffffff 18446742969902956800 /* 0xfffffeff00000100 */ 的EAX = 0猜测。


对于带符号,使用任意精度计算器会有些棘手:

0xffffffff * 0xffffffff

这么少的无符号数当然分为; (0xfffffff0 - 2^32) * 5 -80 /* -0x50 */ ; . + 2^64 // get the 64-bit 2's complement bit-pattern for that negative number 18446744073709551536 /* 0xffffffffffffffb0 */ 0xffffffff,而EDX只是全数,与EAX的高位相同,因为这就是符号扩展的工作原理。

本文链接:https://www.f2er.com/2860849.html

大家都在问