2013-06-30 4 views
6

Hier einige C, in einem Lehrbuch gefunden Ich lerne:Verwendung von Test Anweisung mit dem gleichen registrieren

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

Ich gehe davon aus n bei %edx ist.

Der Assembler-Code erzeugt wird:

testl %edx, %edx 
jle .L5 

Ich verstehe, dass jle Tests für weniger als oder gleich (SF^OF) | ZF. Ich bin mir jedoch nicht sicher, wie diese Anweisung n > 0 entspricht. Kann das jemand erklären?

+2

möglich duplikat von [x86 Assembly - 'testl' eax gegen eax?] (Http://stackoverflow.com/questions/147173/x86-assembly-testl-eax-against-ax) – interjay

+0

Ich glaube nicht, Er benutzt einen anderen Sprungbefehl. – dgamma3

+0

Es ist immer noch ein Vergleich mit 0, Sie können jede Sprunganweisung danach verwenden. – interjay

Antwort

12

Einige davon wurden abgedeckt, aber ich werde ein wenig mehr Details ausfüllen.

Der allgemeine Zweck der test reg,mask-Anweisung testet einen Registerwert auf eine Maske (der Registerwert wird intern mit einer Maske verknüpft) und setzt dann die Statusflags SF, ZF und PF entsprechend dem Ergebnis. [EDIT pro Kommentar von @ChrisDodd] Es ist auch löscht bedingungslos den O (Überlauf) und C (carry) Statusbits. [/ 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 diesem speziellen Beispiel (test eax,eax), wird der Befehl eax AND eax nehmen. Wenn dies erfolgt ist, werden die Bits wie folgt aussehen:

Mit anderen Worten, es ist ein einfacher Test für Null oder negativ. Es ist ein sehr häufiges Muster in der Compiler-Code-Generierung.

+2

Eine kritische zusätzliche Tatsache ist, dass der Test-Befehl bedingungslos die O- und C-Flags löscht. Ohne das wäre es für Vergleiche mit Null nicht sinnvoll. –

+0

@ChrisDodd gute info (+1). Vielen Dank. Wenn es Ihnen nichts ausmacht, füge ich das meiner Vollständigkeit halber hinzu. – lurker

1

TEST "setzt die SF-, ZF- und PF-Statusflags entsprechend dem Ergebnis." (Intel Handbuch, ungefähr TEST).

Also wird SF reflektieren, ob n war negativ, und ZF wird widerspiegeln, ob n war Null.

Es setzt OF auf Null.

So (SF^OF)|ZF vereinfacht zu SF | ZF, so abschließend, der Sprung wird genommen, wenn n <= 0. Das scheint der falsche Weg, also hoffentlich .L5 ist das Etikett nach die Schleife, nicht das Etikett vor der Schleife.

Verwandte Themen