JavascriptProva

Visualizzazione post con etichetta flags. Mostra tutti i post
Visualizzazione post con etichetta flags. Mostra tutti i post

sabato 21 settembre 2013

Registri flag di segno e di parità.

Ecco, approfondiamo un po' queste belle flags.
In particolare, mi incuriosisce la flag di segno.
Vuoi vedere che questa flag diventa NG semplicemente se il risultato di un'operazione ha il primo bit pari a 1?
Per verificarlo, faccio una somma che mi dia il primo bit pari a 1:
text segment public
start:
 mov al,01111111B
 mov bl,10000000B
 add al,bl
 mov ah,4ch
 int 21h
 
text ends
end start
-r
AX=0000  BX=0000  CX=000A  DX=0000  SP=0000  BP=0000  SI=0000  DI=0000
DS=1771  ES=1771  SS=1781  CS=1781  IP=0000   NV UP EI PL NZ NA PO NC
1781:0000 B07F          MOV     AL,7F
-t

AX=007F  BX=0000  CX=000A  DX=0000  SP=0000  BP=0000  SI=0000  DI=0000
DS=1771  ES=1771  SS=1781  CS=1781  IP=0002   NV UP EI PL NZ NA PO NC
1781:0002 B380          MOV     BL,80
-t

AX=007F  BX=0080  CX=000A  DX=0000  SP=0000  BP=0000  SI=0000  DI=0000
DS=1771  ES=1771  SS=1781  CS=1781  IP=0004   NV UP EI PL NZ NA PO NC
1781:0004 02C3          ADD     AL,BL
-t

AX=00FF  BX=0080  CX=000A  DX=0000  SP=0000  BP=0000  SI=0000  DI=0000
DS=1771  ES=1771  SS=1781  CS=1781  IP=0006   NV UP EI NG NZ NA PE NC
1781:0006 B44C          MOV     AH,4C
-
Sì! Verificato! Ovviamente, se stiamo facendo un'operazione senza segno, ce ne freghiamo.

C'è un'altra flag che cambia, la seconda, che da PO diventa PE. Che significa? Giobe, aiutami tu!

Ecco: sarebbe il Parity Flag. Ricordando che in inglese Even e Odd significano Pari e Dispari, PO significa che nel risultato c'è un numero dispari di 1 mentre PE significa numero pari di 1.

Ripasso dell'istruzione CMP e di alcune flags.

Ripassiamo un po' l'istruzione CMP e le flags

Ecco un programmuscolo:
text segment public
start:
 mov al,3
 cmp al,8
 
 mov ah,4ch
 int 21h
 
text ends
end start
In debug, col comando traccia:
c:\Assembly>debug cmp.exe
-t

AX=0003  BX=0000  CX=0008  DX=0000  SP=0000  BP=0000  SI=0000  DI=0000
DS=1771  ES=1771  SS=1781  CS=1781  IP=0002   NV UP EI PL NZ NA PO NC
1781:0002 3C08          CMP     AL,08
-t

AX=0003  BX=0000  CX=0008  DX=0000  SP=0000  BP=0000  SI=0000  DI=0000
DS=1771  ES=1771  SS=1781  CS=1781  IP=0004   NV UP EI NG NZ AC PO CY
1781:0004 B44C          MOV     AH,4C
-
Rivediamo un po' queste flags...

La flag di riporto esprime un riporto o un prestito, e nella sottrazione di numero maggiore da numero minore si genera un prestito, per cui in questo caso la prima flag viene modificat da NC a CY.
La terza flag è quella di riporto ausiliario che esprime il riporto nell'ambito del nibble. In questo caso il riporto c'è, e quindi da NA diventa AC.
La quinta flag è quella del segno, che prende, se non vado errato, il valore del bit più significativo, che in questo caso è 1, e quindi da PL diventa NG.

Vediamo di ricostruire cosa avviene nello specifico in questa sottrazione di numeri binari.
3 - 8 si traduce in binario con 00000011 - 00001000.
Mettiamolo in colonna:

00000011 -
00001000 =
____________
11111011

che, nella lettura con segno equivale a -5, giusto risultato di 8 - 3.

Il mio "trucco" per leggere velocemente i numeri binari negativi è questo. Quando dal bit più significativo c'è una fila ininterrotta di 1, io vado a vedere l'ultimo 1 della fila, e vedo a quale numero "corrisponde", ossia quale valore avrebbe il numero binario senza segno se questo 1 fosse l'unico: in questo caso, se l'ultimo numero della fila fosse l'unico, ossia se fosse 00001000, il byte avrebbe valore di 8.
Quindi vado avanti e considero i restanti 1 come se fossero soli nel byte: in questo caso sono la penultima e l'ultima cifra del byte a essere 1, e se fossero soli il byte avrebbe valore di 3.
Quindi sottraggo al numero calcolato precedentemente, ossia a 8, il secondo numero calcolato, ossia il 3, e cambio di segno il risultato, ottenendo -5.