2013-06-30 17 views
6

Ecco alcuni C, trovato in un libro di testo sto imparando:L'utilizzo di un'istruzione di test con la stessa registrazione

... 
do { 
    ... 
    n--; 
} while (n > 0) 
... 

Presumo n è a %edx.

Il codice assembly prodotta è:

testl %edx, %edx 
jle .L5 

intendo che jle test per inferiore o uguale a (SF^OF) | ZF. Tuttavia non sono sicuro di come questa istruzione corrisponda a n > 0. Qualcuno può spiegarlo?

+2

possibile duplicato di [x86 Assembly - 'testl' eax contro eax?] (Http://stackoverflow.com/questions/147173/x86-assembly-testl-eax-against-eax) – interjay

+0

Non ci credo, sta usando un'istruzione di salto diversa. – dgamma3

+0

È ancora un confronto con 0, è possibile utilizzare qualsiasi istruzione di salto dopo di esso. – interjay

risposta

12

Alcune di queste sono state trattate, ma inserirò un po 'più in dettaglio.

Lo scopo generale dell'istruzione test reg,mask verifica un valore di registro rispetto a una maschera (il valore di registro è internamente ad AND con maschera) e quindi imposta i flag di stato SF, ZF e PF in base al risultato. [EDIT per commento da @ChrisDodd] Si elimina inoltre incondizionatamente la O (overflow) e C stato (carry) bit. [/ EDIT]

SF = sign flag (1 if sign bit is set (a 2's complement negative value)) 
ZF = zero flag (1 if result is 0) 
PF = parity flag (1 if result has an even number of 1 bits) 

In questo esempio specifico (test eax,eax), l'istruzione sta prendendo eax AND eax. Quando questo è fatto, i bit saranno:

SF = 1 if EAX has a negative value (since sign bit will not change when ANDed with itself) 
ZF = 1 if EAX is zero (the only value that yields a zero when ANDed with itself is zero) 
PF = 1 if EAX has an even number of 1 bits 

In altre parole, è un semplice test per zero o negativo. È un modello molto comune nella generazione del codice del compilatore.

+2

Un ulteriore fatto critico è che l'istruzione 'test' cancella incondizionatamente i flag O e C. Senza quello non sarebbe utile per i confronti contro zero. –

+0

@ChrisDodd buone informazioni (+1). Grazie. Se non ti dispiace, lo aggiungerò alla mia risposta per completezza. – lurker

1

TEST "imposta i flag di stato SF, ZF e PF in base al risultato." (Manuale Intel, circa TEST).

Quindi SF rifletterà se n era negativo e ZF rifletterà se n era zero.

Imposta OF su zero.

Quindi (SF^OF)|ZF si semplifica a SF | ZF, quindi in conclusione, il salto verrà effettuato se n <= 0. Questo sembra il modo sbagliato, quindi spero che L5 sia l'etichetta dopo il ciclo, non l'etichetta davanti al ciclo.