Cómo calcular el desbordamiento en operaciones matemáticas ARM

Considerar:

LDR r0,=(1:SHL:31) ; this means r0 contains = 2^31 = 0x80000000

ADDS r0,r0,r0 ; which means r0 = 0x80000000+ 0x80000000.

En primer lugar, sé que es un desbordamiento por lo que parece, pero ¿cómo lo calculo exactamente? ¿Utilizo el método de fuerza bruta, lo convierto a binario y los sumo usando 1 y 0? ¿O hay una forma alternativa?

Además, noté que las banderas se actualizan con N=0 Z=1 C=1 V=1.

Si bien puedo entender por qué C=1, ¿por qué Z y V=1? ¿Por qué 0x80000000+ 0x80000000 es un cero y también tiene un desbordamiento sin firmar?

Respuestas (2)

Sume los dos números y trunque a los 32 bits inferiores (a la derecha) u 8 nibbles.

Entonces, 0x80000000 + 0x80000000 = 0x100000000, luego truncamos y nos queda 0x00000000 en el registro de 32 bits (por lo que el indicador Cero está configurado, solo se preocupa por lo que hay en el registro, o más específicamente lo que estaba en el registro desde el último operación de establecimiento de bandera) con un uno en el bit adicional, que aparece como una bandera de acarreo establecida en el ARM. Cuando está agregando números sin firmar, eso significa que tiene un desbordamiento.

El indicador N indica que el resultado de la última operación de establecimiento de indicadores fue negativo si se interpreta como un número de complemento a 2. Un número en complemento a 2 es negativo si el MSB es 1.

La bandera V indica un desbordamiento en la suma cuando los números se interpretan como números en complemento a 2 (con signo).

Una forma de ver el desbordamiento con signo es que si los dos números que se suman tienen signos opuestos, entonces el desbordamiento es imposible. Si los dos números tienen los mismos signos pero el resultado tiene el signo opuesto al de los operandos, entonces se ha producido un desbordamiento. No hay necesidad de mirar el acarreo.

Ninguno, ambos o cualquiera de los indicadores pueden establecerse, dependiendo de los números.

Por ejemplo, 0x7FFFFFFFF + 0x7FFFFFFFF = 0xFFFFFFFE C = 0, V = 1, Z = 0 indica un desbordamiento si la adición estaba firmada pero no si no estaba firmada.

O 0xFFFFFFFF + 1 = 0x00000000 C = 1, V = 0, Z = 1 indica un desbordamiento si la adición no estaba firmada pero no si estaba firmada.

El núcleo de ARM no sabe qué interpretación está usando, pero proporciona ambos indicadores para que pueda usar el que sea apropiado.

En la mayoría de las circunstancias modernas (no siempre fue tan fácil decir esto), la parte de la ALU que realiza sumas y restas es fundamentalmente independiente de las operaciones con y sin signo. No conoce los valores con signo y no le importan los valores con signo. La ALU simplemente realiza una operación sin firmar y eso es todo lo que hace.

Para la resta, el sustraendo simplemente se invierte y el arrastre de la operación, que además se establece en 0, se establecerá en 1, en su lugar. Eso es todo. Todo es solo una operación AGREGAR con algunas modificaciones realizadas en una de las entradas y el acarreo, si elige SUB en lugar de AGREGAR. Se lleva a cabo exactamente la misma operación ADD, de cualquier manera.

Es increíblemente fácil.

Debido a que algunas operaciones deben extenderse a varias palabras, la ALU incluye una copia de un bit que de otro modo no obtendría: la realización de la operación de palabras. Guarda este bit en el bit de estado C. Esta es una captura simple. Todo lo que hace es tomar una copia de la ejecución del bloque lógico ALU ADD. Si está realizando operaciones sin signo, el bit de estado C le indica si tuvo un desbordamiento aritmético sin signo . (Y probablemente necesite almacenamiento de varias palabras). Pero lo que realmente significa depende totalmente de usted. A la ALU simplemente no le importa. Es solo "ser útil" en caso de que te importe.

El bit de estado Z es 1 si el resultado de la operación ALU es cero y 0 en caso contrario. Por lo general, este es el caso no solo para ADD y SUB, sino también para muchas otras operaciones lógicas: consulte el manual para asegurarse, ya que generalmente hay un mux gigante y un diseñador puede o no usar esta detección para otras operaciones.

El bit de estado Z es muy importante debido a la necesidad muy común de decrementar algún contador y detectar cuando llega a cero, saliendo rápidamente de un bucle. Hay otros usos importantes (operaciones firmadas, incluidas), pero esta es la razón principal. Muy a menudo desea saber cuándo una operación produce un resultado cero exacto. Por lo tanto, los diseñadores agregan la lógica adicional (barata) para ahorrarle una o dos instrucciones y, en su lugar, entregarle la respuesta en bandeja de plata.

El bit de estado V está ahí porque también es barato de generar y puede usarlo si está trabajando con interpretaciones firmadas. Significa un desbordamiento aritmético y se calcula como el XOR del acarreo del siguiente bit más significativo y el propio bit de acarreo. Nuevamente, a la ALU realmente no le importan los valores firmados y no tiene ninguna lógica para observarlos. Es solo calcular una bandera que es útil para detectar el desbordamiento aritmético con signo . Si está configurado, y si cree que está trabajando con valores firmados, entonces tuvo tal desbordamiento. No le importa el bit de estado V si imagina que está realizando operaciones sin firmar.

Entonces,

  1. Si cree que está utilizando valores sin firmar, mire el indicador de estado C para detectar algo que requiera atención adicional. No te importa la bandera de estado V.
  2. Si cree que está utilizando valores con signo, mire el indicador de estado V para detectar algo que requiera atención adicional. No te importa la bandera de estado C.

Dado que no es importante pensar en esto con palabras anchas, podemos volver a las palabras de 3 bits para mantenerlo simple. Aquí, solo hay 8 símbolos:

         Unsigned    Signed     Subtrahend
000          0          0          111
001          1          1          110
010          2          2          101
011          3          3          100
100          4         -4          011
101          5         -3          010
110          6         -2          001
111          7         -1          000

                                     Result          Unsigned            Signed
  Operation     Actual Operation    V C ALU       Interpretation     Interpretation
ADD 011 + 001 = ADD 011 + 001 + 0 = 1 0 100         3 + 1 =  4          3 +  1 = 4 E
ADD 011 + 110 = ADD 011 + 110 + 0 = 0 1 001         3 + 6 =  9 E        3 + -2 = 1
SUB 011 - 001 = ADD 011 + 110 + 1 = 0 1 010         3 - 1 =  2          3 -  1 = 2
SUB 011 - 110 = ADD 011 + 001 + 1 = 1 0 101         3 - 6 = -3 E        3 - -2 = 5 E

De lo anterior (E es un error) puede ver cómo interpretar los bits. En la suma sin signo, C=1 es un error (se requiere acarreo). En la resta sin signo, C=0 es un error (falta de préstamo). En la suma con signo, V=1 es un error (se requiere acarreo con signo). En la resta con signo , V=0 es un error (falla en el préstamo firmado).

Ver también esta discusión para un caso específico de bifurcación condicional firmada .

Muy buena explicación, podrías estar escribiendo libros de texto.
@JosephDoggie ¡Gracias! Agradezco el amable pensamiento. Pero aquí hoy puedes ver dónde Elliot probablemente no estaría de acuerdo contigo. ;)