Estoy tratando de diseñar una CPU instructable de 8 bits en Logisim. ¿Es posible calcular números grandes con una CPU de 8 bits?
En una computadora de 32 bits se pueden calcular números mayores a 32 bits, creo que es un truco de software pero quien me puede explicar como funciona?
Ciertamente es posible trabajar con números muy grandes incluso en computadoras de 8 o 4 bits. No es muy eficiente, pero es posible. La forma de hacerlo es operando sobre los números en piezas, con el apoyo de instrucciones específicas del procesador.
Un microcontrolador común de 8 bits es la serie Atmel AVR. Para sumar números de 8 bits, utiliza una instrucción llamada ADD. Esta instrucción se utiliza para sumar dos valores de registro juntos. Por ejemplo, puedes hacer
LDI R16, 5
LDI R17, 10
ADD R16, R17
; R16 = 15
para sumar R16 y R17 y poner el resultado en R16. Para sumar números de 16 bits, básicamente lo haces varias veces. Sin embargo, hay una trampa: el bit de acarreo. Otra instrucción AVR es ADC, para ADd con Carry. Esto hace exactamente lo mismo que ADD, pero también agrega la bandera de acarreo. Tanto ADD como ADC establecerán la bandera de acarreo si la operación de adición se desborda. Digamos, si agrega 128 a 128, obtiene 0 como resultado con la bandera de acarreo establecida. Si llama a ADC con la bandera de acarreo establecida, agregará 1 al resultado. Aquí hay un ejemplo de adición de 16 bits:
LDI R16, 232
LDI R17, 3
; R17:R16 = 1000
LDI R18, 208
LDI R19, 7
; R19:R18 = 2000
ADD R16, R18
ADC R17, R19
; R16 = 184
; R17 = 11
; R17:R16 = 3000
Esto se puede repetir tantas veces como sea necesario para sumar números grandes. Tenga en cuenta que se requiere una pequeña cantidad de lógica para admitir esto: la capacidad de alimentar la bandera de acarreo en el acarreo del sumador.
Se puede usar un proceso similar para multiplicar números. Realizar multiplicaciones de 16 bits en un procesador de 8 bits requiere 4 multiplicaciones de 8 bits y varias sumas. El procedimiento es exactamente el mismo que multiplicar números a mano, un dígito a la vez, excepto que usa bytes en lugar de dígitos. Deberá multiplicar los cuatro pares de bytes posibles y luego sumarlos de acuerdo con sus valores posicionales. Ejemplo en AVR ASM:
LDI R16, 232
LDI R17, 3
; R17:R16 = 1000
LDI R18, 208
LDI R19, 7
; R19:R18 = 2000
MUL R16, R18
; R1:R0 = R16*R18 (1s place product)
MOVW R3:R2, R1:R0
; R3:R2 = R16*R18
MUL R16, R19
; R1:R0 = R16*R19 (256s place product #1)
CLR R4
ADD R3, R0
ADC R4, R1
; R4:R3:R2 = R16*R18 + 256*R16*R19
MUL R17, R18
; R1:R0 = R17*R18 (256s place product #2)
ADD R3, R0
ADC R4, R1
; R4:R3:R2 = R16*R18 + 256*(R16*R19+R17*R18)
MUL R17, R19
; R1:R0 = R17*R19 (65536s place product)
CLR R5
ADD R4, R0
ADC R5, R1
; R5:R4:R3:R2 = R16*R18 + 256*(R16*R19+R17*R18) + 65536*R17*R19
; R5:R4:R3:R2 = 2000000
Notará que así es exactamente como trabaja con números a mano en papel, pero en lugar de trabajar con dígitos de base 10, la CPU trabaja con bloques de bits del tamaño de una palabra, en este caso, 8 bits.
Si usa una CPU que puede trabajar con más bits a la vez, entonces trabajar con números grandes se vuelve más fácil ya que requiere menos instrucciones. Sin embargo, puede usar las mismas técnicas para trabajar con números más grandes que los que admite directamente el conjunto de instrucciones.
Editar: el compilador AVR GCC contiene un código ensamblador que utilizará para varias operaciones comunes, como la multiplicación y la división, que puede ser una buena referencia sobre cómo se hace este tipo de cosas: https://github.com/gcc-mirror /gcc/blob/master/libgcc/config/avr/lib1funcs.S . Creo que mi multiplicación de 16x16 a 32 debería ser equivalente a __umulhisi3.
int
es de 16 bits), implementada casi con macros que se expanden a instrucciones nativas. De ahí la optimización bastante pobre en la asignación de registros, mezclando cosas (extensión de signo, desplazamiento de bytes) y aritmética (16x16+ mul/div, etc.).Como dijiste, las CPU de 32 bits pueden manejar números mayores de 32 bits, entonces, ¿por qué una CPU de 8 bits no debería poder hacer esto?
Si sumas dos números, comienzas con el último bit de ambos. Si uno de ellos es 1, el resultado es 1, si ambos son 1, el resultado es 0, y hay que llevar un 1 al cálculo del segundo bit.
Para el segundo bit, tienes los dos bits de los números y el bit llevado. Si uno o los tres son 1, el resultado es 1. Si dos o todos son 1, nuevamente debe llevar un 1 al cálculo del tercer bit.
Esto generalmente se hace en hardware, es decir, hay puertas lógicas, simplemente coloca los números en las entradas y obtiene la salida. Tenga en cuenta que si tiene un sumador de 8 bits, también obtiene la llamada bandera de acarreo de la suma de los 8 bits.
Si solo está agregando dos números de 8 bits, la bandera de acarreo solo indica si el resultado es mayor que 255, el número más grande que puede contener un entero de 8 bits (sin signo).
Si tiene números más grandes, ahora comienza a agregar los bits del segundo byte y tiene en cuenta la bandera de acarreo de la adición anterior durante la adición del primer bit de este byte.
La única diferencia es que una CPU de 32 bits puede agregar 32 bits de una vez, por lo que agregar números de 64 bits consta de dos pasos, mientras que una CPU de 8 bits necesita 8 pasos.
De esta manera, puede agregar números de cualquier tamaño en cualquier CPU. Todas las demás matemáticas se hacen de manera similar, la CPU más pequeña solo necesita más pasos.
Cuando sumas dos números con lápiz y papel, trabajas de derecha a izquierda, sumando dos dígitos, registrando el resultado y llevando cualquier desbordamiento. Sumar números grandes en una computadora funciona de la misma manera. Cada número está representado por un conjunto de "dígitos" donde cada "dígito" es una palabra de computadora: 8 o 32 bits de ancho en sus dos ejemplos. Cuando se suman dos de esos números, es exactamente el mismo proceso: sumar dos "dígitos", registrar el resultado y llevar cualquier desbordamiento. La diferencia es que cada dígito representa un valor entre 0 y 2^8 (para un procesador de 8 bits) o un valor entre 0 y 2^32 (para un procesador de 32 bits). Si se siente cómodo pensando en términos de bases numéricas, la suma con lápiz y papel funciona en base 10,
Ignacio Vázquez-Abrams
yippie