Diferença entre Adicionar e adicionar

Estou confuso sobre a diferença entre Adicionar e adicionar.

A referência da instrução MIPS diz:
  • adicionar (com transbordamento)
  • Adicionar sem sinal (sem transbordamento)

o meu entendimento é usar adicionar com operandos assinados e adicionar com operandos não assinados.

mas vamos considerar este exemplo (com apenas 6 bits):

overflow
|
V
1 | 1 1 1  <- carry
  | 1 1 1 1 0 1 +
  | 1 1 1 1 1 0 =
-----------------
  | 1 1 1 0 1 1
E este é o meu raciocínio:
  • Se eu considerar o primeiro e o segundo operando assinado números (dois complemento), então o resultado é correto (-3 + -2 = -5) e eu não quero uma exceção de transbordamento. Então eu usaria addu para evitar esta exceção, mas, embora o resultado seja o mesmo, o nome sugere usar addu é para números não assinados!
  • Se eu considerar os números do primeiro e do segundo operando sem sinal , Então eu quero uma exceção a ser levantada (porque 61 + 62 não é igual a 59). Assim, eu usaria o add para levantar a exceção, e não o addu, como o nome sugere a fazer.
Agora as minhas perguntas são:
  • assumindo que os operandos são assinados (negativos no exemplo acima) números, devo usar addu (como o meu raciocínio sugere) ou devo usar add (como o nome sugere)?
  • assumindo que os operandos são números Sem sinal (positivos), devo usar Adicionar (como o meu raciocínio sugere) ou adicionar (como o nome sugere)?
 12
Author: collimarco, 2013-05-19

5 answers

Os nomes das instruções são enganadores. Use addu tanto para os operandos assinados como não assinados, se você fizer não deseja uma armadilha no overflow.

Utilize add Se precisar de uma armadilha para transbordar por alguma razão. A maioria das línguas não quer uma armadilha no overflow assinado, por isso add raramente é útil.

 10
Author: markgz, 2013-05-21 00:27:59

Se estiver a usar números assinados, deve usar add Se quiser gerar uma armadilha quando o resultado transbordar.

Se estiver a usar números Sem sinal, deve usar sempre {[[2]} e verificar o excesso da adição comparando o resultado com qualquer um dos números (se o resultado for inferior aos operandos, então a adição transbordou).

Aqui vai um excerto para mostrar como é que você iria verificar o excesso na adição não assinada:

    li $a1, 0xFFFF0FFF
    li $a2, 0x00010000

    addu $a3, $a1, $a2  # This unsigned addition overflows (set $a3 to $a1+$a2)
    bgt $a1, $a3, overflowed
    bgt $a1, $a2, overflowed
    # If you get here, unsigned addition did not overflow
  # your code goes here...
overflowed:
    # If you get here, unsigned addition overflowed
  # your code goes here...
 5
Author: gusbro, 2016-03-29 14:12:00

OVERFLOW is NOT as declared in the question, this carry bit is NOT a overflow bit, in the given example there is NO OVERFLOW, overflow is when:

MSB1 = 1 && MSB2 = 1 && MSBofRESULT = 0
OR
MSB1 = 0 && MSB2 = 0 && MSBofRESULT = 1 

Então fique com add ele vai flag transbordar, e o bit de transporte em seu exemplo (que não é um transbordamento) não vai incomodá-lo. addu faz o mesmo, excepto que nunca é levantada nenhuma excepção.

 3
Author: Stack Player, 2016-10-12 21:34:16

Basicamente, ambos os opcodes são uma adição assinada. então em MIPS eles usam 31 bits para armazenar dados, o número máximo é (2 aumento para 31)-1 e 1 bit é reservado para armazenar o sinal para os números. Como delineado acima, a diferença básica entre" Adicionar "e" adicionar " é que o primeiro lança uma exceção quando o número do resultado é maior do que o número máximo do que 31 bit occupy. O último executa sem mostrar qualquer aviso.

Eg, adição máxima de 3 bits num = (2**(n-1)) - 1 minumem num = - (2**(n-1)) então, no nosso caso max = 3 e min = -4

li $t1,3
li $t2,1
add $t3,$t1,$t2 -----> throws an arthimetic overflow exception

addu $t3,$t1,$t2 ------> t3 = -4
É isso.
 2
Author: Henok Tesfaye, 2018-04-29 08:55:06
Na verdade, não é um excesso no seu exemplo. Um overflow ocorre quando o carry no bit do sinal não é igual ao carry out do bit do sinal. Em seu exemplo, embora a realização do bit do sinal é " 1 "(o aparentemente transbordamento), o bit do carry into sign também é"1". Portanto, nesta condição MIPS não vai considerá-lo como um transbordamento. O padrão de como o transbordamento ocorre é realmente correspondente a se o resultado está correto. Isto é, se o resultado estiver fora do intervalo seus bits podem representar, um overflow ocorre. Por exemplo, se você adicionar dois números de 4-bit 0111 (7) e 0010 (2) juntos, você obter um overflow uma vez que o resultado (9) está fora do intervalo um número de 4-bit pode representar (-8 a 7). Se você olhar para a aritmética:
0111 (7) + 0010 (2) = 1001 (-7)

Você pode ver que apesar de não haver nenhuma realização do bit do sinal, o resultado ainda está incorreto. Portanto, este é um overflow (e MIPS irá detectá-lo).

 0
Author: endurancist, 2018-02-28 20:49:41