Assembly 寄存器中存储的数字有多大

Assembly 寄存器中存储的数字有多大,assembly,bigint,extended-precision,Assembly,Bigint,Extended Precision,这是一个基本问题,但假设我想将寄存器$t2、t3和$t4中的3个数字相乘。假设每个寄存器只能容纳8位,当我们将三个数字相乘时,结果可能大于8位。如果大于8位,如果每个寄存器只能容纳8位,那么结果如何存储在寄存器$t0中?在这种特定情况下,算术单元将设置一个Nohow。这是众所周知的算术溢出 有时您可以更改运算符的顺序以避免此类溢出。F.e.if(a+b>INT\u MAX).您可以编写if(a>INT\u MAX-b).等等 有时您应该使用int64而不是int32,或者使用double而不是f

这是一个基本问题,但假设我想将寄存器$t2、t3和$t4中的3个数字相乘。假设每个寄存器只能容纳8位,当我们将三个数字相乘时,结果可能大于8位。如果大于8位,如果每个寄存器只能容纳8位,那么结果如何存储在寄存器$t0中?

在这种特定情况下,算术单元将设置一个Nohow。这是众所周知的算术溢出

有时您可以更改运算符的顺序以避免此类溢出。F.e.
if(a+b>INT\u MAX).
您可以编写
if(a>INT\u MAX-b).
等等

有时您应该使用
int64
而不是
int32
,或者使用
double
而不是
float


有时您应该使用大数字库,如。

通常CPU有某种指令,将两个寄存器相乘,并给出两倍大的结果,分布在多个寄存器上。这是实现扩展精度算法所必需的

例如,在amd64上,要将两个64位数字相乘并得到128位结果,您需要执行以下操作:

mov rax, qword ptr [t2]
mul qword ptr [t3]
; the result is now in rdx : rax
mov qword ptr [result], rax
mov qword ptr [result + 8], rdx

要将三个64位数字相乘并得到一个192位的结果,您必须通过将上述相关部分相乘并将它们相加来实现扩展精度乘法。

您刚刚发现算术溢出——点击您最喜欢的搜索引擎。不同的ISA在这里做不同的事情,您可能会得到两半(因此有两项产出),可能只有下半部分,可能还有其他内容。@harold谢谢,这正是我想谈的。如果我得到两个输出,它是否将一个输出存储在一个寄存器中,另一个输出存储在另一个寄存器中?是否同时完成?不熟悉AMD64 ISA,但这是有意义的。那么,结果如何存储在rdx和rax中?我猜是a汇编程序或编译器会自动为您执行此操作?@deryl:不,这是
mul
指令的工作方式。它将
rax
中的值乘以操作数,然后将结果存储在
rdx:rax
对中。amd64,也称为x64,是x86的一种64位扩展,这是所有64位英特尔处理器运行的方式。酷!感谢you@deryl:x86:,对于IMUL的单操作数形式也是如此。MIPS有专用的HI和LO寄存器用于保存完整乘法结果,以及专用的movhi和movlo指令用于将结果复制到通用寄存器,IIRC。ARM有单独的32x32=>32b指令(UMUL)和全乘法UMULL,后者使用4个操作数(2个输入和2个输出)。下面是一个C和asm输出的示例:@deryl:godbolt也有AVR gcc4.5。AVR是一个8位RISC微控制器,其中寄存器实际上是8位。不幸的是,gcc只调用一个库函数来实现等效函数(带有char和short):