Bun venit pe SkullBox!

Bine ai venit, Vizitator. Trebuie să te autentifici sau să îţi creezi un cont.
Ai pierdut sau nu ai primit emailul care conţine codul de activare al contului?

Autentifică-te cu numele de utilizator, parola şi precizează durata sesiunii.
  Pagini: [1]
  Imprimă  
[ Tutorial ] Notiuni elementare ASM  (Vizualizari 1178)
!_30
*

Deconectat Deconectat

Mesaje: 628

WWW
[ Tutorial ] Notiuni elementare ASM, Apr 21, 2008, 22:43

Ca tot m-am apucat sa cotrobai prin assembler si sa incerc sa inteleg instructiunile de baza , am decis sa fac un tutorial . Nu am sa prezint chestii foarte complicate sau alte trasnai , cat lucruri simple care cred ca valoareaza foarte mult daca sunt intelese pe deplin . Hai sa incepem :

   Cred ca prima data ar fi bine sa discutam despre registri . Cum assemblerul are rolul sa mareasca viteza de executie si sa optimizeze programul acesta are acces si al registri . Ce fac acesti registri ? Va ajuta sa stocati/transferati date mai repede . Acum intrebarea normala ? La ce m-ar ajuta chestia asta ? Procesoarele din ziua de azi sunt destul de rapide si nu prea se simte diferenta . Eh .. o sa se simta . Sa presupunem ca avem un for care incrementeaza un contor [ o variabila i ] de un milion de ori . De fiecare data cand se intra in bucla variabila i este incrementata . Ce inseamna asta ? Acces la memorie .. timp pierdut ! Am codat un exemplu banal de bucla for in C++ . Incrementez din 1 in 1 [ contorul i ] si la fiecare iteratie incrementez o variabila a [ la fel ca si contorul ] . Asta o fac de 1.000.000.000 ori . Cronometrat dureaza in jur de 3-4 secunde . Aceeasi bucla for [ cu acelasi rezultat ] dar scrisa in assembler dureaza in jur de 1.5-2 secunde . Nu-i mare branza , dar ganditi-va ce-ar fi sa facem bucla aceea for la randul ei de un miliard de ori . Ati prins ideea .
   
    Exemple de registri

   - registri pe 8 biti [ un octet ] : AL,AH,BL,BH,CL,CH,DL,DH. Ideea e ca seturile de doi cate doi sunt analoage , doar ca incep cu alta litera . Ce-i interesant este L-ul si H-ul care se repeta la fiecare set in parte . Poate ti-ai dat seama ca vine de la LOW si HIGH . Putin ciudat nu ? Daca punem cap la cap un octet AH cu un AL obtinem , normal , doi octeti [ unul langa altul ] sau un cuvant . Chestia interesanta este ca acesti doi octeti pusi cap la cap AH AL formeaza tocmai un registru de 16 biti [ un cuvant / doi octeti ] , defapt sunt practic in componenta lui . Discutam imediat .
  - registri pe 16 biti [ doi octeti ] : AX,BX,CX,DX . Sa luam exemplul AX . AX-ul practic este setul AL,AH . Da , asta este . Nu e bine sa gandim registri ca pe niste variabile . Ci ca niste portiuni de memorie . Un registru mare [ o sa discutam imediat ] are mai multe bucati . Primul octet este AL , al doilea AH [ primii biti LOW , urmatorii AH ] , dar acestia doi la un loc pot insemna in acelasi timp si AX si tot asa . Ce vreau sa spun prin asta ? Daca tu introduci o anumita valoare [ sa spunem 2 ] in AL si apoi introduci valoarea 15 in AX risti ca valoarea ta 2 din AL sa fie suprascrisa de valoarea 15 . De ce ? Te-ai prins tu .
  - registri pe 32 de biti [ doua cuvinte / patru octeti ] : EAX,EBX,ECX,EDX . Ideea e cam la fel , cum explicam mai sus . Daca introduci sa spunem in AX valoarea 15 [ poti sa introduci si o valoare mai mare , ca na , suntem pe doi octeti ] si apoi in EAX valoarea 32 , risti ca valoarea ta din AX sa fie suprascrisa . Normal , EAX-ul incepe sa scrie de pe bitii de pe pozitia cea mai de jos [ cei din AL ] si tot asa ..

   Nici eu nu vreau sa risc sa fac prea mare tam-tam pe baza acestor registri , sa nu spun vreo prostie . Hai deci sa dsicutam despre niste instructiuni care ne pot ajuta sa transferam date . Defapt sa ne jucam cu datele din registri . Mentionez ca folosesc Visual C++ pentru compilare . Am vazut ca prin asta merge sa introduci inline ASM ceva de genu _asm { } . Nu stiu daca e cea mai buna alegere , dar in fine , merge .

    Instructiuni

* mov destinatie,sursa


  Ce face comanda de mai sus ? Move [ muta / transfera ] date de la sursa la destinatie . Atentie , datele trebuie sa fie de acelasi tip . Nu putem transfera intr-un octet doi octeti , ca n-avem loc , normal . Voi prezenta un mic exemplu mai jos [ de mentionat ca nu este un program intreg C++ ci doar o fasie de cod ] :

Citat
char a;
   _asm
      {
         mov al,0;
         mov a,al;
      }
cout << int(a) << endl;
Ce face codul de mai sus ? In primul rand combina C++ cu ASM . In al doilea rand transfera in variabila a valoarea 0 . In al treilea rand ai sa spui : " optimizare de unde ? nu era mai usor sa scriem in C++ a=0 ? " . Ai dreptate , dar aici e doar un exemplu cum poti sa te joci cu instructiunea mov si cum sa ai grija ca sursa si destinatia sa fie de acelasi tip [ octet - octet , cuvant - cuvant , dublu cuvant - dublu cuvant ] . Stim ca tipul char este pe un octet si registrul al are o bucata de un octet , deci toate lucrurile sunt bune . Prima data transferam in al valoarea 0 , apoi in a valoarea lui al , adica 0 . Apoi afisam valoarea intreaga a lui a [ nu caracterul cu codul ASCII 0  ] .  Acum ca stii cam ce sunt aia registri poti sa modifici codul de mai sus cand a este un int [ pe patru octeti ] .

   Ce spuneam mai sus ? Nu trebuie sa vedeti registri ca pe niste variabile [ si odata pusa valoarea acolo , acolo ramane ] . Trebuie sa-i vedeti ca pe niste bucati dintr-un spatiu de memorie mai mare si odata modificat pe registri de dimensiuni mai mare se modifica pe toti cei de dedesupt . Exemplu :

Citat
char a;
   short b;
   int c;
   _asm
   {
      mov al,15;
      mov a,al;
      mov ax,31;
      mov a,al;
   }
   cout << int(a) << endl;
- Ce se intampla in cod ? In registrul de 8 biti [ primii 8 biti din locatia mare de memorie pentru registri , LOW ] punem valoarea 15 . Dar punem si in AX valoarea 31 . Atentie : AX incepe sa puna biti de la inceputul lui AL [ pana il umple ] si apoi continua pe AH . Deci modificat AX , modificam implicit si AL-ul , deci valoarea lui AL va deveni 31.

* add destinatie,sursa

  Adauga in destinatie , sursa . Deci calculeaza destinatie+sursa . In exemplul de mai jos se adauga la 0 [ valoarea initiala a lui a , valoarea 2 ] .

Citat
int a=0;
   _asm
   {
         add a,2;
   }

   cout << a << endl;
* sub destinatie,sursa

   Scade din valoarea destinatiei , valoarea sursei .

Citat
char a=5;
   _asm
   {
         sub a,2
   }
   cout << int(a) << endl;
* inc destinatie

  Mareste cu o unitate valoarea destinatiei . In exemplul de mai jos , la afisare va aparea 3 . N-are rost sa mai dau exemplul si de instructiunea dec care face exact inversul lui inc . Scade o unitate din valoarea data .

Citat
int a=2;
   _asm
   {
         inc a
   }
   cout << a << endl;
Ca veni si partea frumoasa a lucrurilor si ca tot ne-am plictisit de banalele operatii de adunare si scadere haideti sa trecem la inmultire

* mul sursa  ( pentru numerele fara semn )

   Ciudat ! Pe cine cu cine si unde stocheaza rezultatul ?  Buna intrebare . O inmultire e ceva de genu a*b si se poate stoca in c=a*b . Noi avem doar sursa . Sursa se inmulteste cu un registru [ implicit ] de acelasi numar de octeti cu ea . Practic daca sursa este pe un octet se va inmulti cu AL [ pe un octet ] . Unde stocam rezultatul ? Daca inmultim doi octeti , normal ca rezultatul o sa fie mai mare de un octet . El va fi repartizat in AX . Un mic exemplu mai jos va clarifica lucrurile :

Citat
char a=3;
   short b;
   _asm
   {
      mov al,2
      imul a;
      mov b,ax


   }
   cout << b << endl;
Variabila a ocupa un octet . Daca execut mul a [ cum a este pe un octet ] se va inmulti variabila a cu registrul echivalent dimensiunii sale al . Cum in al am mutat 2 si in variabila a avem 3 , in ax vom avea 6 . Destul de interesant nu ?

   Sa presupunem ca vrem sa inmultim doua cuvinte [ un cuvant are doi octeti ] . Mutam in ax valoarea 2 si in a valoarea 4 [ a este acum de tipul short , un cuvant si ax este de doi octeti = un cuvant ] . Practic rezultatul ar trebui stocat intr-o variabila de doua cuvinte cum ar fi eax sa zicem . Dar , nu este asa . Rezultatul va fi stocat in perechea de registre DX , AX . Primii biti in AX si ceilalti in DX . O sa explic imediat de ce .

   Sa presupunem ca vrem sa inmultim patru octeti cu patru octeti . Unde va fi stocat rezultatul ? Nu avem/nu putem folosi registri de 64 de biti [ pe care ar incapea rezultatul inmultirii ] . Rezultatul este stocat in perechea de registri EDX,EAX analog cu mai sus . De ce insa mai sus rezultatul nu e stocat direct intr-un registru de 4 octeti ? Din motive de compatibilitate intre procesoare vechi/noi . Cand nu erau registri de 32 de biti nu se putea pune rezultatul inmultirii a doi registri de 16 biti , intr-un registru de 32 de biti [ ca nu exista ] . Deci a fost pus in DX , AX . Acum , la procesoarele mai noi unde au aparut registri de 32 de biti , nu se putea modifica ce a fost inainte din motive de compatibilitate . Ar fi trebuit compilat totul dupa aia ca sa mai functioneze . Asta e toata chestia .

   Pentru inmultire de numere cu semn se foloseste imul sursa la fel ca mul de mai sus . Cam asta e ideea , nu intru in detalii .


   Ultima [ dar nu cea din urma , nici ultima pana la urma , dar ultima din acest tutorial ] este inmultirea . Inmultire , impartire , se leaga , deci teoretic ar trebui sa se lege si modul in care se fac aceastea in limbaj de asamblare . Da si practic se leaga .

* div sursa

   Iar ai intrat in ceata . Impartire formata doar dintr-o singura chestie ? Impartirea e ceva de genu a=b/c . Dar observi ca acum , rezultatul impartirii nu ar trebui sa mai ocupe un spatiu dublu ca numar de octeti , ci teoretic unul de doua ori mai mic , ca impartim doar . Operandul care se da este c-ul . La ce impart . Daca impart la operand pe un octet [ sa zicem ca ar fi un short sau un registru pe un octet gen cl ] deimpartitul este AX , adica registrul de doua ori mai mare . Catul impartirii se transfera in AL si restul se transfera in AH .
   Cam ciudat , dar la restul ? Daca vreau sa impart la un operand pe doi octeti ? Nu cumva deimpartitorul nu o sa fie EAX ci perechea DX,AX ? Ai dreptate . Sa fi atent in cazul in care deimpartitul intra pe doi octeti sa setezi DX-ul pe 0 si in AX sa pui rezultatul . Iti dai tu seama de ce [ daca vrei sa-ti mearga impartirea ] . Catul va fi pus in AX si restul in DX .
   Analog daca vrem sa impartim la operandul pe 4 octeti gen ecx , deimpartitul va fi EDX, EAX catul fiind pus in EAX si restul in EDX .

   Mare branza , nimic interesant [ NOT ] . Ca sa nu termin tutorialul fara pic de interactivitate am sa discut un pic si despre salturi . Cum sa facem bucla for despre care discutam mai devreme . Dar de data asta in asm .

   N-am sa intru prea tare in instructiunile de salt/etichete sau alte chestii ca este destul de mult de discutat despre ele . Am sa prezint doar la general cateva chestii necesare pentru a intelege exemplu de mai jos [ da , am sa dau prima data exemplul ca sa te fac curios ] :

Citat
_asm
      {
         mov al,0;
         mov eax,1;
e1: cmp eax,5
      jae e2
         inc eax
         jmp e1
e2:
   mov a1,eax;
      }
      cout << "val a " <Ce face codul de mai sus ? O bucla ! Initial avem in registrul al valoarea 0 [ registrul al va fi folosit drept suma, la fiecare iteratie se va incrementa ] . Registrul eax e initializat cu valoarea 1 [ gandeste-te la eax ca la un contor i ] . e1 si e2 sunt etichete . O sa discutam mai tarziu putin ce inseamna si cu ce ne ajuta o eticheta.
   Ca intr-un while/for comparam contorul , la noi eax , cu valoarea pana la care vrem sa ajungem . Aici cmp face aceasta comparatie . Dar ce face jae ? Jae compara doua numere fara semn daca primul numar este mai mare sau egal decat al doilea . Ce nevoie am eu ca al meu contor sa fie mai mare sau egal cu 5 . Am nevoie , in cazul in care eax [ contorul ] este mai mare sau egal cu 5 atunci va sari la afisare . Am aflat si rolul etichetei . Practic jae-ul sare executia codului la eticheta pe care i-am dat-o . Cand nu mai avem nevoie sa facem iteratii mergem la e2 si afisam / calculam / transferam , tot ce avem chef .
   In cazul in care nu s-a sarit la sfarsit [ nu s-a terminat bucla ] trece peste jae e2 la urmatoarea instructiune care incrementeaza pe eax . Asta inseamna ca eax inca este mai mic decat 5 [ sau probabil egal , daca in urma incrementarii trebuie sa iesim din bucla ] , dar trebuie sa sarim [ jmp asta face , sare la o eticheta , neconditionat , adica fara conditia cmp ] sa verificam daca mai continuam sau sarim la afisare . Si tot asa .



   Oricum , ideea de baza nu a fost sa prezint cine stie ce sofisticarie ci doar niste elemente de baza despre ASM . In cazul in care aveti ceva de completat sau semnalati vreo / mai multe erori nu ezitati .
   Ne mai auzim !
Memorat

Agkelos
*

Deconectat Deconectat

Mesaje: 5229

WWW
[ Tutorial ] Notiuni elementare ASM, Apr 22, 2008, 05:27

Daca un incepator pune mana pe un manual de asamblare va fi putin surprins. Nu se invata programare la modul concret ci de fiecare data se incepe cu calculul zonelor de memorie, cu marimile registrilor, cu stive, cu alocarea memoriei etc. In majoritaea cartilor de asamblare se prezinta asamblarea asa cum e, adica "hard-core". Tu nu explici toata vorbaraia aia, dar e un tutorial hand-on care pentru un incepator valoreaza mai mult decat pagini de teorie despre paginarea memoriei. Cine vrea mai mult are acum un punct de pornire. Good job ! Winking
Memorat



Problemele se rezolva pe forum. Nu trimiteti PM ca nu va ajut.
Pentru urgente, skullbox at skullbox . info.
3Nigma
*

Deconectat Deconectat

Mesaje: 981

WWW
[ Tutorial ] Notiuni elementare ASM, Apr 22, 2008, 11:04

pentru mine sunt mai valoroase notiuni de repartizare a memoriei ... Smile
!_30 felicitari pentru initiativa,il consider tare reusit  :cool:
Memorat



Search for knowledge in the darkest places and in the blackest hours! You might get lucky and find more than you are looking for...

"Ambition is a lame excuse for the ones that are not brave enough to be lazy..."
vladiii
*

Deconectat Deconectat

Mesaje: 166

[ Tutorial ] Notiuni elementare ASM, Apr 23, 2008, 20:00

Brava.
Multi folosesc Dev-C++ in loc de Visual C++, iar acolo se foloseste sintaxa at&t care e mai dificila si nu merita invatata. Asa ca... folositi asta:
Cod:
#include <iostream>
#include <conio.h>
using namespace std;
char a;
int main()
{
    asm(".intel_syntax noprefix");
    asm("mov al, 1");
    asm("mov _a, al");
    asm(".att_syntax noprefix");
    cout << int(a) << endl;
    getch();
    return 0;
}
*Aceiasi chestie cu primul tau cod !
Bafta !
« Ultima modificare: Dec 21, 2008, 01:49 de către emi » Memorat

emi
*

Deconectat Deconectat

Mesaje: 814

[ Tutorial ] Notiuni elementare ASM, Iun 14, 2008, 17:18

stiati ca exista turbo pascal 7 ?

procedure nimic(w:word);assembler;
asm
  mov ax, w
  add ax, 2
end;
Memorat
astan
*

Deconectat Deconectat

Mesaje: 357

[ Tutorial ] Notiuni elementare ASM, Iun 14, 2008, 18:14

Citat din mesajul lui: vladiii
Brava.
Multi folosesc Dev-C++ in loc de Visual C++, iar acolo se foloseste sintaxa at&t care e mai dificila si nu merita invatata. Asa ca... folositi asta:
Cod:
#include <iostream>
#include <conio.h>
using namespace std;
char a;
int main()
{
    asm(".intel_syntax noprefix");
    asm("mov al, 1");
    asm("mov _a, al");
    asm(".att_syntax noprefix");
    cout << int(a) << endl;
    getch();
    return 0;
}
*Aceiasi chestie cu primul tau cod !
Bafta !
Sintaxa AT&T e mai dificila si nu merita invatata ???
Merita invatata, mai ales daca lucrezi pe sisteme Unix/Linux ... Si nici nu e nici mai "dificila", nici mai usoara decat sintaxa Intel. E doar o alta sintaxa.
Cunosc ambele sintaxe (plus inca 3 limbaje de asamblare in afara de cel pt x86), si nu ma deranjeaza in nici un fel sintaxa AT&T
« Ultima modificare: Dec 21, 2008, 01:49 de către emi » Memorat
DarkByte
*

Deconectat Deconectat

Mesaje: 2441

WWW
[ Tutorial ] Notiuni elementare ASM, Iun 14, 2008, 19:15

^^ emi, ce vrei sa spui cu Turbo Pascal 7 ?
Memorat

Light travels faster than sound. This is why some people appear intelligent until they speak.

Quidquid latinum dictum sit, altum viditur.

Challenge
*

Deconectat Deconectat

Mesaje: 98

[ Tutorial ] Notiuni elementare ASM, Iun 15, 2008, 08:44

Cred ca vrea sa spuna ca poti folosi si TP7 ca ASM... (cred)
Memorat
emi
*

Deconectat Deconectat

Mesaje: 814

[ Tutorial ] Notiuni elementare ASM, Iun 16, 2008, 17:02

Citat din mesajul lui: DarkByte
^^ emi, ce vrei sa spui cu Turbo Pascal 7 ?
eu am folosit TP7 pentru aproape tot ce am scris in asm.
inclusiv program TSR (terminate and stay resident).
Nu prea am folosit C pentru ca cerea prea multe resurse  Laughing
(aveam un 8086 de 4.77MHz cu 640KB de RAM)

In plus ai un IDE misto, debugger inclus, etc.
Memorat
astan
*

Deconectat Deconectat

Mesaje: 357

[ Tutorial ] Notiuni elementare ASM, Iun 16, 2008, 17:24

Citat din mesajul lui: emi
Citat din mesajul lui: DarkByte
^^ emi, ce vrei sa spui cu Turbo Pascal 7 ?
eu am folosit TP7 pentru aproape tot ce am scris in asm.
inclusiv program TSR (terminate and stay resident).
Nu prea am folosit C pentru ca cerea prea multe resurse  Laughing
(aveam un 8086 de 4.77MHz cu 640KB de RAM)

In plus ai un IDE misto, debugger inclus, etc.
C-ul consuma mai multe resurse decat Pascal-ul ? Nu stiam asa ceva.
Si in C ai debugger, nu-i problema ...
Memorat
DarkByte
*

Deconectat Deconectat

Mesaje: 2441

WWW
[ Tutorial ] Notiuni elementare ASM, Iun 16, 2008, 17:44

^ Nu stiu daca intr-adevar consuma mai multe resurse, dar cu siguranta compileaza mai repede. Tested on an XT @ 8 MHz, with 640 kb RAM si 33 MB hdd (fratele mai mare al compului lui emi)

^^ emi, discutia de fata nu are in vedere calculatoarele de atunci. Faptul ca !_30 a ales sa-si faca tutorialul in C ... a fost dreptul lui. Comenteaza doar daca probleme cu ceva legat de cod.

Bafta
Memorat

Light travels faster than sound. This is why some people appear intelligent until they speak.

Quidquid latinum dictum sit, altum viditur.

emi
*

Deconectat Deconectat

Mesaje: 814

Răspuns: [ Tutorial ] Notiuni elementare ASM, Dec 21, 2008, 02:03

Subiect: Tutorial ASM

Deci a fost clar ce sunt aia registrii ?
Ca eu cind am deschis o carte de ASM, nu explicau ca la bite, ce e aia.

Deci sunt 4 registrii asa zis generali. A, B, C, D in procesor.
Daca lucrezi pe 16 biti ei se numesc: AX, BX, CX, DX.
Daca lucrezi pe 8 biti: AX e facut din AH*16+AL, la fel si BH, BL, sau CH, CL, sau DH, DL

AX, e de obicei numit acumulator, ca e folosit pentru operatii aritmetice
BX, e de uz general
CX, e numit contor, ca e folosit in majoritatea operatiilor ca si.. (ce credeti) contor  Laughing
DX, e numit de obicei DATA, fara explicatii

Operatii importante:

Atribuire:
MOV AX,BX
inseamna: AX := BX

Adunare:
ADD AX,BX
inseamna: AX:=AX+BX

Scadere:
SUB AX,BX
inseamna: AX:=AX-BX

Pentru mai mult, va recomand Norton Guide. Va urma.
« Ultima modificare: Dec 21, 2008, 02:06 de către emi » Memorat
astan
*

Deconectat Deconectat

Mesaje: 357

Răspuns: [ Tutorial ] Notiuni elementare ASM, Dec 21, 2008, 02:49

Pentru arhitectura x86 (32 de biti), cei mai importanti registri sunt:

Registri de uz general (pe 32 de biti):
EAX - folosit de obicei ca si registru acumulator
EBX - folosit ca pointer catre datele din segmentul DS
ECX - folosit de obicei ca si counter pentru operatii pe string-uri sau bucle
EDX - folosit de obicei ca pointer I/O
ESI - folosit de obicei ca:
-> pointer catre datele din segmentul DS
-> sursa in cadrul operatiilor pe string-uri
EDI - folosit de obicei ca:
-> pointer catre datele din segmentul ES
-> destinatie   in cadrul operatiilor pe string-uri
ESP - stack pointer, in segmentul SS
EBP - pointer catre datele aflate pe stiva, in segmentul SS

Registri de segment (pe 16 biti):
CS - segment de cod
DS - segment de date
SS - segment de stiva
ES, DS, FS, GS - data segments

EFLAGS - registru de status, control si system flags (32 de biti)

EIP - instruction pointer (32 de biti)

Registri de control: CR0, CR1, CR2, CR3, CR4

System table registers: GDTR, LDTR, IDTR, Task Register

Registri de debug: DR0 - DR7

Registri pentru FPU

Registri MMX (MM0 - MM7)

Registri XMM (XMM0 - XMM7, MXCSR)
« Ultima modificare: Dec 21, 2008, 03:34 de către astan » Memorat
emi
*

Deconectat Deconectat

Mesaje: 814

Răspuns: [ Tutorial ] Notiuni elementare ASM, Dec 21, 2008, 03:00

Instructiuni de incrementere si decrementare.

mai pe romineste adauga 1 sau scade 1

INCREMENTARE:
INC AX

DECREMENTARE
DEC AX

Aici trebuie facute niste precizari: Exista un registru in procesor care se numeste FLAG e pe 16 biti, si mai nou e si pe 32
el contine "stegulete" pentru ce operatiuni se desfasoara

link: http://sandpile.org/ia32/eflags.htm


Deci in momentul in care DEC AX are valoarea 0, o instructiune de tipul JUMP daca e zero se scrie ca JZ adresa
echvalent cu:
IF AX==0 GOTO adresa;

deci ZF (zero flag) se seteaza automat daca rezultatul ultimei operatii a fost 0 sau nu, si nu conteaza daca a fost AX, e valabil in general.

Mai exista si OF adica overflow Flag, in caz ca ai depasit.
de exemplu:
MOV AX, FFFF
INC AX
JO AmDepasitValoarePe16Biti

JO inseamna JUMP daca OF ( overflow flag e setat ).

In momentul in care aritmetric se depaseste valoarea, se seteaza automat CF ( carry flag )

de aceea exista ADC = add with carry.
exemplu:

MOV DX,0
MOV AX,FFFF
INC AX
ADC DX,0

Va urma.

P.S.: a se vedea si http://www.skullbox.info/board/algoritmi-si-tehnici-de-programare/scurt-tutorial-asm/
« Ultima modificare: Dec 21, 2008, 11:49 de către emi » Memorat
emi
*

Deconectat Deconectat

Mesaje: 814

Răspuns: [ Tutorial ] Notiuni elementare ASM, Dec 24, 2008, 19:34

Instructiunile de tip JUMP.

Exista in procesor un registru care se numeste IP = Instruction Pointer.
O instructiune de tip jump, modifica acest registru.

IP nu e accesibil direct, mai tirziu o sa vorbesc si despre asta.

O instructiune de tip jump simpla (pe 16 biti):

JMP ( neconditionat la ) adresa;

Sau in cazul cind e pe 32 de biti:
JMP FAR adresa;

un exemplu mai putin obisnuit e cel de a obtine registrul IP:

call @1;
@1:
pop ax;
// acum ax contine IP

instructiunea call e echivalenta cu push IP, jmp @1;
va trebui sa vorbesc despre push si pop, dar toate la timpul lor.

Ce este de fapt IP (Instruction Pointer) ? este locatia de unde procesorul ia instructiunea curenta, o executa, vede ce lungime are, iar aceasta lungime sa o notam cu LIC = Lungime Instructiune Curenta; Procesorul face operatiunea IP+=LIC in mod automat, si executa urmatoarea instructiune.

P.S. rog pe ceilalti in domeniu sa ma completeze.
« Ultima modificare: Dec 24, 2008, 22:10 de către emi » Memorat
SkullAds
Ecspert
ReclAmator
* * * * *
Google AdSense

Gen: Bărbat
Mesaje: Multe

Reclama AdSense,
 

 
   


Pagini: [1]
  Imprimă  
 
Schimbă forumul:  

Ethical hacking and programming community
Powered by SMF 1.1.7 | SMF © 2006-2008, Simple Machines LLC
Traducerea în limba română © 2006-2007 www.smf.ro