Frage

Ich versuche, einige Versammlung zu verstehen.

Die Montage wie folgt, ich bin an der testl Zeile:

000319df  8b4508        movl   0x08(%ebp), %eax  
000319e2  8b4004        movl   0x04(%eax), %eax  
000319e5  85c0          testl  %eax, %eax  
000319e7  7407          je     0x000319f0  

Ich versuche, diesen Punkt von testl zwischen %eax und %eax zu verstehen? Ich denke, die Besonderheiten dessen, was dieser Code ist nicht wichtig, ich bin nur mit sich selbst, den Test zu verstehen versuchen - wäre nicht der Wert immer wahr sein

War es hilfreich?

Lösung

Es prüft, ob eax 0, oder oben oder unten. In diesem Fall wird der Sprung genommen, wenn eax 0 ist.

Andere Tipps

Die Bedeutung von test ist und zusammen die Argumente, und prüfen Sie das Ergebnis für Null. Also dieser Code prüft, ob EAX Null ist oder nicht. je springt, wenn Null.

BTW, erzeugt dies eine kleinere Anweisung als cmp eax, 0 was der Grund ist, dass Compiler wird es auf diese Weise im Allgemeinen tun.

Der Testbefehl hat eine logische UND-Verknüpfung zwischen den Operanden, aber nicht das Ergebnis zurück in ein Register nicht schreiben. Es werden nur die Flags aktualisiert.

In Ihrem Beispiel des Test eax, eax wird gesetzt, den Null-Flag, wenn EAX gleich Null ist, der Zeichen-Flag, wenn das höchste Bit gesetzt und einige andere Flaggen als auch.

Die Jump if equal (je) Anweisung springt, wenn der Null-Flag gesetzt ist.

Sie können den Code zu einem besser lesbaren Code wie folgt übersetzen:

cmp eax, 0
je  somewhere

Das hat die gleiche Funktionalität erfordert aber einige Bytes mehr Code-Raum. Das ist der Grund, warum der Compiler einen Test anstelle eines vergleichen emittiert.

test ist wie and , außer es FLAGS nur schreibt, die beide ihre Eingänge unmodifizierten verlassen. Mit zwei andere Eingänge, dann ist es sinnvoll, für die Prüfung, wenn einige Bits alle Null sind, oder wenn mindestens eins gesetzt ist. (Z.B. test al, 3 setzt ZF wenn EAX ein Vielfaches von 4 ist (und daher sowohl seiner niedrigen 2 Bits auf Null gesetzt).


test eax,eax setzt alle Flags genau die gleiche Art und Weise, die a href <= "http://www.felixcloutier.com/x86/CMP.html" rel = "noreferrer"> cmp eax, 0 würde :

  • CF und geräumte (AND / Test nicht immer, dass, und Null Subtraktion erzeugt nie einen Übertrag)
  • ZF, SF und PF entsprechend dem Wert in EAX. (a = a&a = a-0)

(Außer für den veralteten AF (Auxiliary-Übertrags-Flag, verwendet durch ASCII / BCD Anweisungen). TEST lässt es undefiniert , aber CMP setzt sie „entsprechend dem Ergebnis“ Da. Null Subtraktion kann nicht einen Übertrag vom 4. bis 5. Bit, CMP sollte immer klar AF) erzeugen.


TEST kleiner (keine unmittelbare) und manchmal schneller (können Makro-Sicherung in eine Vergleichs- und Zweig UOP auf mehreren CPUs in mehr Fällen als CMP). , dass das bevorzugte Idiom macht test ein Register für die Prüfung für Null oder nicht.

Der einzige gemeinsame Grund für die Verwendung CMP mit einer sofortigen 0 ist, wenn man gegen einen Speicheroperanden vergleichen möge (zB cmpb $0, (%esi) für einen abschließenden Null-Byte am Ende eines impliziten Länge C-String zu überprüfen).


AVX512F fügt kortestw k1, k2 und AVX512DQ / BW (Skylake aber nicht KNL) hinzufügen ktestb/w/d/q k1, k2 , die auf AVX512 Maskenregister (k0 arbeiten ..k7), aber immer noch gesetzt regelmäßige FLAGS wie test der Fall ist, die gleiche Art und Weise, dass die ganze Zahl OR oder AND Anweisungen tun.

kortestw k1,k1 ist der idiomatische Weg / verzweigen cmovcc / setcc basierend auf einem AVX512 vergleichen Ergebnis ersetzen SSE / AVX2 (v)pmovmskb/ps/pd + test oder cmp.


Die Verwendung von jz vs. je kann verwirrend sein.

jz und je sind buchstäblich die gleiche Anweisung , dh die gleiche Opcode in der Maschine Code. Sie tun das Gleiche, aber haben unterschiedliche semantische Bedeutung für die Menschen . Disassembler (und in der Regel asm Ausgabe von Compilern) werden immer nur eine verwenden, so dass die semantische Unterscheidung verloren.

cmp und sub ZF gesetzt, wenn ihre beiden Eingänge gleich sind (das heißt das Subtraktionsergebnis gleich 0 ist). je (Sprung, wenn gleich) ist das semantisch relevant Synonym.

test %eax,%eax / and %eax,%eax wieder setzt ZF, wenn das Ergebnis Null ist, aber es gibt keine „Gleichheit“ zu testen. ZF nach dem Test sagt Ihnen nicht, ob die beiden Operanden gleich sind. So jz (springen, wenn Null) ist das semantisch relevant Synonym.

Dieser Code-Snippet ist von einem Unterprogramm, das einen Zeiger auf etwas, wahrscheinlich eine Struktur oder ein Objekt gegeben wurde. Die zweite Linie dereferenziert diesen Zeiger einen Wert aus dem Dinge holen - möglicherweise selbst einen Zeiger oder vielleicht auch nur ein int, als sein zweiten Glied gespeichert (Offset + 4). Die 3. und 4. Zeile testet diesen Wert für Null (NULL, wenn es ein Zeiger) und überspringen Sie die folgenden wenige Operationen (nicht dargestellt), wenn es Null ist.

Der Test auf Null manchmal als codiert zu einem sofortigen wörtlichen Nullwert zu vergleichen, aber der Compiler (oder ein Mensch?), Der dies schrieb könnte ein testl op schneller laufen würde gedacht haben - unter Berücksichtigung aller die moderne CPU Sachen wie Pipelining und Umbenennung registrieren. Es ist von der gleichen Tasche von Tricks, die die Idee des Löschens eines Registers mit XOR EAX hält, EAX (was ich in Colorado auf jemandes Nummernschild gesehen haben!) Eher als die offensichtliche, aber vielleicht langsamer MOV EAX, # 0 (i verwenden eine ältere Schreibweise ).

In asm, wie Perl, TMTOWTDI.

Wenn EAX Null wird es die bedingte Sprung ausführen, sonst wird es die Ausführung bei 319e9 fortsetzen

In einigen Programmen können sie für einen Pufferüberlauf zu prüfen, verwendet werden. An der Spitze des zugewiesenen Platzes ein 0 gesetzt. Nachdem die Daten in den Stapel eingegeben wird, sieht es für die 0 am Anfang des zugewiesenen Raum der zugewiesene Raum nicht überschwemmt, um sicherzustellen, ist.

Es wurde in der stack0 Ausübung von Exploits-Übungen verwendet zu überprüfen, ob es überschwemmt wurde und wenn es gab nicht und es gab es eine Null ist, wäre es angezeigt „Versuchen Sie es erneut“

0x080483f4 <main+0>:    push   ebp
0x080483f5 <main+1>:    mov    ebp,esp
0x080483f7 <main+3>:    and    esp,0xfffffff0
0x080483fa <main+6>:    sub    esp,0x60                     
0x080483fd <main+9>:    mov    DWORD PTR [esp+0x5c],0x0 ;puts a zero on stack
0x08048405 <main+17>:   lea    eax,[esp+0x1c]
0x08048409 <main+21>:   mov    DWORD PTR [esp],eax
0x0804840c <main+24>:   call   0x804830c <gets@plt>
0x08048411 <main+29>:   mov    eax,DWORD PTR [esp+0x5c] 
0x08048415 <main+33>:   test   eax,eax                  ; checks if its zero
0x08048417 <main+35>:   je     0x8048427 <main+51>
0x08048419 <main+37>:   mov    DWORD PTR [esp],0x8048500 
0x08048420 <main+44>:   call   0x804832c <puts@plt>
0x08048425 <main+49>:   jmp    0x8048433 <main+63>
0x08048427 <main+51>:   mov    DWORD PTR [esp],0x8048529
0x0804842e <main+58>:   call   0x804832c <puts@plt>
0x08048433 <main+63>:   leave
0x08048434 <main+64>:   ret

könnten wir die jg sehen , jle Wenn testl %edx,%edx. jle .L3we könnte einfach finden jle ist Klage (SF^OF)|ZF, wenn% edx Null ist, ZF = 1, aber wenn% edx nicht Null und -1 ist, nach dem testl, 0 OF = und die SF = 1, so das Flag = true, der Sprung implementieren .sorry, mein Englisch ist schlecht

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top