Carry / Overflow e sottrazione in x86
-
12-11-2019 - |
Domanda
Sto cercando di avvolgere la testa in giro per il trabocco e portare bandiere in x86.
Come lo capisco, per l'aggiunta dei numeri di complemento firmati 2, i flag possono essere generati solo in uno dei quattro modi (i miei esempi sono numeri a 4 bit):
- .
- pos + pos= neg (overflow)
- .
- 0111 + 0001= 1000 (7 + 1= -8)
- pos + neg= pos (trasporta)
- .
- 0011 + 1110= 0001 (3 + -2= 1)
- neg + neg= neg (carry)
- .
- 1111 + 1111= 1110 (-1 + -1= -2)
- neg + neg= pos (overflow & carry)
- .
- 1000 + 1001= 0001 (-8 + -7= 1)
Quindi, in assemblaggio X86, subrattare B da A Genera le stesse flag come aggiungendo A e -B?
- 1000 + 1001= 0001 (-8 + -7= 1)
Soluzione
Ecco una tabella di riferimento che potrebbe aiutare.Questo mostra un esempio di ogni possibile combinazione delle 4 flag aritmetiche che possono derivare dalle istruzioni aggiuntive e secondarie su x86.'h' 'ud' e 'd' stand per esagono, decimale non firmata e firmata rappresentazioni decimali di ciascun valore.Ad esempio, la prima riga per Sub dice 0xFF - 0xFE= 0x1 senza flag set.
Ma, penso che la storia breve sia che la risposta di Alex è corretta.
. 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
Altri suggerimenti
Tutte le 4 combinazioni dei valori di trasporto e di overflow sono possibili durante l'aggiunta o la sottrazione.Puoi vedere altri esempi in Questa risposta .
Questa risposta contiene una prova del fatto che il trasporto che ottieni da A-B
è l'inverso del trasporto tuOttieni da A+(-B)
.Il codice da parte del primo link sfrutta questa proprietà per attivare ADC
in SBB
.
Il valore della bandiera del trabocco firmato, tuttavia, deve essere lo stesso per A-B
e A+(-B)
AgCode perché dipende dal fatto che il risultato abbia o meno il corretto bit del segno e in entrambi i casi il bit di segno sarà lo stesso.