Ho pensato che il punto 2 del complemento era che le operazioni potevano essere implementate allo stesso modo per i numeri firmati e non firmati. Wikipedia even specifically lists multiply as one of the operations that benefits. Quindi, perché x86 ha istruzioni separate per ciascuna, mul
e imul
? È ancora vero per x86-64?Perché le istruzioni di moltiplicazione con segno e senza segno sono diverse su x86 (-64)?
risposta
L'addizione e la sottrazione sono le stesse, così come la metà inferiore di un multiplo. Un multiplo completo, tuttavia, non lo è. Semplice esempio:
In 32 bit complemento a due, -1 ha la stessa rappresentazione come la quantità senza segno 2 ** 32 - 1. Tuttavia:
-1 * -1 = +1
(2**32 - 1) * (2**32 - 1) = (2**64 - 2**33 + 1)
(Si noti che i bassi 32-bit entrambi i risultati sono gli stessi, questo è quello che intendo quando dico che "la metà inferiore del multiplo" è la stessa).
Il risultato sarà lo stesso per le versioni 2 e 3 dell'operando, tranne per il fatto che le istruzioni mul e imul differiscono nel modo in cui impostano i flag CF e OF (carry e overflow).
Pensa ai due casi: -1 * -1 rispetto a 0xFFFFFFFF * 0xFFFFFFFF in termini di overflow e ti verrà l'idea.
La moltiplicazione di due numeri a 16 bit produce un risultato a 32 bit. Anche se uno dei numeri è "1", il processore estenderà effettivamente l'altro a 32 bit. Il processo di estendere un numero ad una lunghezza di bit più lunga è una delle operazioni che è diversa per i valori firmati e non firmati (l'altra operazione significativa in cui il segno importa è il confronto della grandezza, che è anche una parte essenziale della divisione).
Per quale intervallo di operandi posso aspettarmi che mul e imul forniscano risultati identici bit a bit? Quando entrambi gli operandi sono positivi e il loro risultato non supera 2 ** 63 - 1? (ovvero, quando il risultato non firmato è troppo piccolo per capovolgere il bit di segno) –
@JosephGarvin: No, non appena si raggiunge un solo bit rispetto alla lunghezza originale, sono necessarie istruzioni separate. Si consideri ad es. '-1 * 1 = -1' contro' 0xFFFFFFFF * 1 = 0xFFFFFFFF'. –
Ah, certo, questo ha senso. –