2012-10-25 15 views
76

Mögliche Duplizieren:
x86 Assembly - ‘testl’ eax against eax?Der Punkt Test% eax% eax

Ich bin sehr sehr neu in Assembler-Programmierung, und ich versuche zur Zeit um die Baugruppe zu lesen Sprache aus einer Binärdatei generiert. Ich habe über

test %eax,%eax 

oder test %rdi, %rdi laufen, etc. etc. Ich bin sehr verwirrt, was dies tut. Sind die Werte in %eax, %eax nicht gleich? Was testet es? Ich habe irgendwo gelesen, dass es die AND Operation macht ..... aber da sie den gleichen Wert haben, würde es nicht einfach %eax zurückgeben?

Das folgende ist nur ein Beispiel, wo ich diese Verwendung gefunden:

400e6e:  85 c0     test %eax,%eax 
    400e70:  74 05     je  400e77 <phase_1+0x23> 

Ich dachte je springt, wenn die beiden Werte gleich sind, verglichen werden ...... gut, weil %eax gut ist, selbst, In welcher Situation würden wir nicht springen?

Ich bin ein Anfänger zu Programmierung im Allgemeinen, also würde ich es sehr schätzen, wenn jemand mir das erklären könnte. Vielen Dank!

+4

Da einige Antworten etwas unklar erscheinen, möchte ich darauf hinweisen, dass 'TEST' andere Flaggen außer' ZF' aktualisiert. Siehe Referenz der Befehlssatz. – Jester

+0

@Jester behoben (in meiner Antwort), tut mir leid. –

+0

Ein weiteres mögliches Duplikat: [Was macht die 'test'-Anweisung?] (Http://stackoverflow.com/q/6002079) – jww

Antwort

95

CMP subtrahiert die Operanden und setzt die Flags. Es setzt nämlich das Null-Flag, wenn die Differenz Null ist (Operanden sind gleich).

TEST setzt das Null-Flag, ZF, wenn das Ergebnis der UND-Operation Null ist. Wenn zwei Operanden gleich sind, ist deren bitweises UND gleich null, wenn beide null sind. TEST setzt auch das Vorzeichen-Flag, SF, wenn das höchstwertige Bit im Ergebnis gesetzt ist, und das Paritäts-Flag, PF, wenn die Anzahl der gesetzten Bits gerade ist.

JE [Jump wenn Equals] testet das Null-Flag und springt, wenn das Flag gesetzt ist. JE ist ein Alias ​​von JZ [Jump if Zero], so dass der Disassembler nicht basierend auf dem Opcode einen auswählen kann. JE ist so benannt, weil das Null-Flag gesetzt ist, wenn die Argumente CMP gleich sind.

So

TEST %eax, %eax 
JE 400e77 <phase_1+0x23> 

springt, wenn die %eax Null ist.

+3

Wo finde ich Informationen wie diese? –

+5

nämlich? Die Liste der x86-Anweisungen [ist auf Wikipedia] (http://en.wikipedia.org/wiki/X86_instruction_listings), die auch eine [Spezifikation durch Intel] verbindet (http://www.intel.com/content/www/) us/de/processors/architects-software-developer-manuals.html) sowie [eine andere (ziemlich lesbare) Referenz auf Wayback-Maschine] (http://www.archive.org/web/20100407092131/http://home .comcast.net/~ fbui/intel.html). [Ein Tutorial] (http://en.wikibooks.org/wiki/X86_Assembly) ist auch auf Wikibooks verfügbar. –

+0

ja, das ist die Information, die ich gesucht habe –

9

Dies überprüft, ob EAX Null ist. Die Anweisung test führt bitweise AND zwischen den Argumenten, und wenn EAX Null enthält, setzt das Ergebnis die ZF oder ZeroFlag.

+3

Dies ist die Standardmethode. Man könnte auch cmp% eax, 0 (unmittelbar) für "Klarheit für Anfänger" machen, aber das würde zu einem längeren Befehl (auch weniger effizient) kodieren. –

2

Sie haben Recht, dass test "und" s die beiden Operanden sind. Aber das Ergebnis wird verworfen, das Einzige, was bleibt, und das ist der wichtige Teil, sind die Flaggen. Sie sind gesetzt und das ist der Grund, warum die Anweisung test verwendet wird (und existiert).

JE springt nicht wenn gleich (es hat die Bedeutung, wenn die Anweisung vor war ein Vergleich), was es wirklich tut, springt es, wenn das Flag gesetzt ist.Und da es eines der Flags ist, das von test gesetzt wird, hat diese Befehlsfolge (test x, x; je ...) die Bedeutung, dass sie gesprungen wird, wenn x 0 ist.

Für Fragen wie diese (und für weitere Details) Ich kann nur ein Buch über x86 Anleitung, zB empfehlen selbst wenn es wirklich groß ist, ist die Intel-Dokumentation sehr gut und präzise.

3

test ist eine nicht-destruktive and, es gibt das Ergebnis der Operation nicht zurück, aber es setzt die Flags entsprechend. Um zu wissen, was es wirklich für Sie testet, müssen Sie die folgenden Anweisungen überprüfen. Oft wird out verwendet, um ein Register gegen 0 zu prüfen, möglicherweise gekoppelt mit einem bedingten Sprung jz.

32

Einige x86-Anweisungen sind so konzipiert, dass sie den Inhalt der Operanden (Register) unverändert lassen und bestimmte interne CPU-Flags wie das Null-Flag (ZF) setzen/entsperren. Sie können an der ZF als ein wahres/falsches boolesches Flag denken, das sich in der CPU befindet. In diesem speziellen Fall führt der TEST-Befehl ein bitweises logisches AND aus, verwirft das tatsächliche Ergebnis und setzt/setzt das ZF entsprechend dem Ergebnis des logischen und: Wenn das Ergebnis Null ist, setzt es ZF = 1, andernfalls es ZF = 0 setzt

bedingte Sprunganweisungen wie JE ausgelegt sind für das springen in der ZF aussehen/notjumping so Test und JE zusammen äquivalent einen bedingten Sprung basierend auf dem Wert eines speziellen Register auszuführen:

Beispiel:

TEST EAX, EAX
JE some_address

die CPU auf "some_address" springen, wenn und nur wenn ZF = 1, mit anderen Worten, wenn und nur wenn AND (EAX, EAX) = 0, die in drehen kann auftreten, wenn und nur wenn EAX == 0

das Äquivalent C-Code ist:

if(eax == 0) 
{ 
    goto some_address 
} 
Verwandte Themen