Scopul testului %eax %eax [duplicat] (Programare, Asamblare, X86, Att)

pauliwago a intrebat.

Posibil duplicat:
Ansamblu x86 – ‘testl’ eax față de eax?

Sunt foarte foarte nou în programarea în limbajul de asamblare, iar în prezent încerc să citesc limbajul de asamblare generat de un binar. Am dat peste

 test   %eax,%eax

sau test %rdi, %rdi, etc. etc. Sunt foarte confuz cu privire la ceea ce face acest lucru. Nu cumva valorile din %eax, %eax sunt aceleași? Ce testează? Am citit undeva că face AND operațiune…..dar din moment ce sunt aceeași valoare, nu ar trebui să returneze doar %eax?

Următorul este doar un exemplu în care am găsit această utilizare:

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

Am crezut că je sare dacă cele două valori comparate sunt egale……bine, deoarece %eax este bine, în sine, în ce situație NU am sări?

Sunt începător în programare în general, așa că aș aprecia foarte mult dacă cineva mi-ar putea explica acest lucru. Mulțumesc!

Comentarii

  • Pentru că unele răspunsuri par puțin neclare în această privință, precizez că TEST actualizează și alte stegulețe în afară de ZF de asemenea. Consultați referința setului de instrucțiuni. –  > Por Jester.
  • @Jester fixat (în răspunsul meu), îmi pare rău. –  > Por John Dvorak.
  • Un alt posibil duplicat: Ce înseamnă test instrucțiune face? –  > Por jww.
5 răspunsuri
John Dvorak

CMP sustrage operanzii și setează stegulețele. Și anume, setează stegulețul zero dacă diferența este zero (operanzii sunt egali).

TEST setează stegulețul zero, ZF, atunci când rezultatul operației AND este zero. Dacă doi operanzi sunt egali, operația AND a acestora pe biți este zero atunci când ambii sunt zero. TEST setează, de asemenea, indicatorul de semn, SF, atunci când bitul cel mai semnificativ este setat în rezultat, precum și indicatorul de paritate, PF, atunci când numărul de biți setați este par.

JE [Jump if Equals] testează indicatorul zero și sare dacă acesta este activat. JE este un alias al lui JZ [Jump if Zero], astfel încât dezasamblatorul nu poate selecta una dintre ele pe baza codului operațional. JE se numește astfel deoarece flag-ul zero este setat dacă argumentele pentru CMP sunt egale.

Deci,

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

sare dacă %eax este zero.

Comentarii

Gianluca Ghettini

Unele instrucțiuni x86 sunt concepute pentru a lăsa conținutul operanzilor (registre) așa cum sunt și doar pentru a seta/dezactiva indicatori interni specifici ai CPU, cum ar fi zero-flag (ZF). Puteți să vă gândiți la ZF ca la un steguleț boolean adevărat/false care se află în interiorul CPU.

În acest caz particular, instrucțiunea TEST efectuează o operație logică AND pe biți, aruncă rezultatul real și activează/dezactivează ZF în funcție de rezultatul operației logice: dacă rezultatul este zero, activează ZF = 1, altfel activează ZF = 0.

Instrucțiunile de salt condiționat, cum ar fi JE, sunt concepute pentru a se uita la ZF pentru a efectua saltul/ne-saltul, astfel încât utilizarea TEST și JE împreună este echivalentă cu efectuarea unui salt condiționat bazat pe valoarea unui registru specific:

exemplu:

TEST EAX,EAX
JE some_address

procesorul va sări la „o anumită adresă” dacă și numai dacă ZF = 1, cu alte cuvinte dacă și numai dacă AND(EAX,EAX) = 0, ceea ce la rândul său se poate întâmpla dacă și numai dacă EAX == 0.

codul C echivalent este următorul:

if(eax == 0)
{
    goto some_address
}

ppeterka

Acesta verifică dacă EAX este zero. Instrucțiunea test efectuează o instrucțiune de tip bitwise AND între argumente, iar dacă EAX conține zero, rezultatul setează ZF, sau ZeroFlag.

Comentarii

  • Acesta este modul standard de a face acest lucru. De asemenea, pentru „claritate pentru începători”, se poate face și cmp %eax, 0 (imediat), dar acest lucru ar însemna o instrucțiune mai lungă (și mai puțin eficientă). –  > Por Aki Suihkonen.
flolo

Aveți dreptate, că test „și”-urile celor doi operanzi. Dar rezultatul este aruncat, singurul lucru care rămâne, și asta e partea importantă, sunt stegulețele. Acestea sunt setate și acesta este motivul pentru care test instrucțiunea este folosită (și există).

JE sare nu atunci când este egal (are semnificația atunci când instrucțiunea anterioară a fost o comparație), ceea ce face cu adevărat, sare atunci când ZF indicator este activat. Și cum acesta este unul dintre stegulețele care este setat de către testaceastă secvență de instrucțiuni (test x,x; je….) are semnificația că sare când x este 0.

Pentru întrebări de acest gen (și pentru mai multe detalii) pot doar să vă recomand o carte despre instrucțiunile x86, de exemplu, chiar și atunci când este foarte mare, documentația Intel este foarte bună și precisă.

Jens Björnhager

test este o persoană nedistructivă and, nu returnează rezultatul operației, dar setează registrul flags în mod corespunzător. Pentru a ști ce testează cu adevărat, trebuie să verificați următoarea (următoarele) instrucțiune(e). Adesea, out este utilizat pentru a verifica un registru față de 0, eventual cuplat cu o instrucțiune jz salt condițional.