transporte/estouro e subtração em x86
-
12-11-2019 - |
Pergunta
Estou tentando entender o estouro e carregar sinalizadores em x86.
Pelo que entendi, para adição de números complementares de 2 com sinal, os sinalizadores só podem ser gerados de quatro maneiras (meus exemplos são números de 4 bits):
- pos+pos = neg (estouro)
- 0111 + 0001 = 1000 (7 + 1 = -8)
- pos+neg = pos (transportar)
- 0011 + 1110 = 0001 (3 + -2 = 1)
- neg + neg = neg (transportar)
- 1111 + 1111 = 1110 (-1 + -1 = -2)
- neg+neg = pos (estouro e transporte)
- 1000 + 1001 = 0001 (-8 + -7 = 1)
Então, na montagem x86, subtrair B de A gera os mesmos sinalizadores que adicionar A e -B?
Solução
Aqui está uma tabela de referência que pode ajudar.Isto mostra um exemplo de todo possível combinação dos 4 sinalizadores aritméticos que podem resultar das instruções ADD e SUB no x86.'h' 'ud' e 'd' representam representações hexadecimais, decimais sem sinal e decimais com sinal de cada valor.Por exemplo, a primeira linha de SUB diz 0xFF - 0xFE = 0x1 sem sinalizadores definidos.
Mas acho que o resumo é que a resposta de Alex está correta.
ADD
A B A + B Flags
--------------- ---------------- --------------- -----------------
h | ud | d | h | ud | d | h | ud | d | OF | SF | ZF | CF
---+------+-------+----+------+-------+----+------+-------+----+----+----+---
7F | 127 | 127 | 0 | 0 | 0 | 7F | 127 | 127 | 0 | 0 | 0 | 0
FF | 255 | -1 | 7F | 127 | 127 | 7E | 126 | 126 | 0 | 0 | 0 | 1
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0
FF | 255 | -1 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 1
FF | 255 | -1 | 0 | 0 | 0 | FF | 255 | -1 | 0 | 1 | 0 | 0
FF | 255 | -1 | FF | 255 | -1 | FE | 254 | -2 | 0 | 1 | 0 | 1
FF | 255 | -1 | 80 | 128 | -128 | 7F | 127 | 127 | 1 | 0 | 0 | 1
80 | 128 | -128 | 80 | 128 | -128 | 0 | 0 | 0 | 1 | 0 | 1 | 1
7F | 127 | 127 | 7F | 127 | 127 | FE | 254 | -2 | 1 | 1 | 0 | 0
SUB
A B A - B Flags
--------------- ---------------- --------------- -----------------
h | ud | d | h | ud | d | h | ud | d || OF | SF | ZF | CF
----+------+-------+----+------+-------+----+------+-------++----+----+----+----
FF | 255 | -1 | FE | 254 | -2 | 1 | 1 | 1 || 0 | 0 | 0 | 0
7E | 126 | 126 | FF | 255 | -1 | 7F | 127 | 127 || 0 | 0 | 0 | 1
FF | 255 | -1 | FF | 255 | -1 | 0 | 0 | 0 || 0 | 0 | 1 | 0
FF | 255 | -1 | 7F | 127 | 127 | 80 | 128 | -128 || 0 | 1 | 0 | 0
FE | 254 | -2 | FF | 255 | -1 | FF | 255 | -1 || 0 | 1 | 0 | 1
FE | 254 | -2 | 7F | 127 | 127 | 7F | 127 | 127 || 1 | 0 | 0 | 0
7F | 127 | 127 | FF | 255 | -1 | 80 | 128 | -128 || 1 | 1 | 0 | 1
Outras dicas
Todas as 4 combinações dos valores de transporte e estouro são possíveis ao adicionar ou subtrair.Você pode ver mais exemplos em esta resposta.
Esta resposta contém uma prova do fato de que o transporte que você recebe A-B
é o inverso do carry que você obtém de A+(-B)
.O código do primeiro link explora esta propriedade para transformar ADC
em SBB
.
O valor do sinalizador de overflow assinado, entretanto, deve ser o mesmo para ambos A-B
e A+(-B)
porque depende se o resultado tem ou não o bit de sinal correto e em ambos os casos o bit de sinal será o mesmo.