Când scrieți un program în asamblare, scrieți doar comenzi către procesor. Comenzile către procesor sunt pur și simplu coduri sau coduri de operații sau opcode. Opcodele sunt de fapt "text lizibil" - versiuni de coduri hexazecimale. Din acest motiv, asamblatorul este considerat limbajul de programare cel mai de jos, totul din asamblare este convertit direct în coduri hexazecimale. Cu alte cuvinte, nu aveți un compilator care transformă un limbaj de nivel înalt într-un limbaj de nivel scăzut, asamblor convertește codul de asamblare numai în datele.
În această lecție vom discuta câteva opcode care sunt relevante pentru calcul, operații bitrate etc. Alte opcode: comenzi de salt, comparații, etc, vor fi discutate mai târziu.
Numerele din asamblare pot fi reprezentate într-un sistem binar, zecimal sau hexazecimal. Pentru a arăta în ce sistem este utilizat numărul, este necesar să introduceți o literă după număr. Pentru sistemul binar este scris litera b (exemplu: 0000010b, 001011010b), nu puteți specifica nimic pentru sistemul zecimal după numărul sau specificați d litere (exemple: 4589, 2356d), pentru sistemul hexazecimal este necesar să se precizeze litera h, numărul hexazecimal este necesar să se scrie la zero la început (exemple: 00889h, 0AC45h, 056Fh, F145Ch greșit, C123h).
Prima echipă va fi bine cunoscută tuturor MOV-urilor. Această comandă este folosită pentru a copia (ignora numele comenzii) valori de la un loc la altul. Acest "loc" poate fi un registru, o locație de memorie sau o valoare imediată (numai ca valoare sursă). Comanda Sintaxa:
Puteți copia o valoare dintr-un registru în altul.
de exemplu: această comandă NU este permisă:
Acest opcod încearcă să pună o valoare DWORD (32 biți) într-un octet (8 biți). Acest lucru nu se poate face prin comanda mov (există și alte comenzi pentru aceasta).
Și aceste comenzi sunt corecte, deoarece sursa și receptorul nu diferă în mărime:
De asemenea, puteți obține o valoare din memorie și puteți pune ego-ul în registru. De exemplu, să luăm următoarea schemă de memorie:
(Fiecare bloc reprezintă un octet)
Valoarea offset este indicată aici ca octet, dar de fapt aceasta este o valoare pe 32 de biți. Luați exemplul 3A, aceasta este, de asemenea, o valoare pe 32 de biți: 0000003Ah. Doar pentru a economisi spațiu, unii folosesc mici compensări.
Uită-te la decalajul de 3A din tabelul de mai sus. Datele la acest offset sunt 25, 7A, 5E, 72, EF, etc. Pentru a pune o valoare de la offset 3A, de exemplu, într-un registru, utilizați și comanda mov:
Mijloace: puneți o valoare cu o dimensiune DWORD (32 biți) din memorie, cu un decalaj de 3Ah în registrul eax. După executarea acestei comenzi, eax va conține valoarea 725E7A25h. Este posibil să fi observat că este - o inversare a ceea ce este în memorie: 25 7A 5E 72. Acest lucru se datorează faptului că valorile sunt stocate în memorie, folosind formatul endian mic. Aceasta înseamnă că octetul cel mai puțin semnificativ este stocat în octetul cel mai semnificativ: ordinea octeților înapoi în față. Cred că aceste exemple vor arăta acest lucru:
- Valoarea dword (32 biți) 10203040 hex este stocată în memorie ca: 40, 30, 20, 10
- cuvânt (16 biți) 4050 hexazecimal este stocat în memorie ca: 50, 40
Să revenim la exemplul de mai sus. Puteți face acest lucru și cu alte dimensiuni:
Probabil că ați înțeles deja că prefixul ptr înseamnă că trebuie să țineți memorie din memorie. Și prefixul înainte de ptr denotă dimensiunea datelor:
Uneori dimensiunea poate fi omisă:
Deoarece EAX - registru de 32 de biți, asamblorul își dă seama că aceasta necesită, de asemenea, o valoare de 32 de biți, în acest caz, memoria de offset 403045h.
De asemenea, puteți avea valori imediate:
Această comandă este o scriere la EDX registru, valoarea 5006. Consolele [și], sunt utilizate pentru a obține valoarea din memorie (în paranteze este offset), fără paranteze, este doar o valoare imediată.
De asemenea, puteți utiliza registrul ca locație de memorie (trebuie să fie 32 biți în programele pe 32 de biți):
In cx mov, [eax], procesorul arată în primul rând, o valoare (= celule de memorie) cuprinde eax, valoare care este apoi stocat în aceeași celulă de memorie și stochează această valoare (cuvânt, 16 biți, deoarece receptorul, cx, este 16- bit registru) în CX.
- 1: pune 100 în ecx
- 2: pune 200 în eax
- 3: Plasați valoarea de la ecx (= 100) pe stivă (plasată mai întâi)
- 4: Plasați valoarea de la eax (= 200) pe teancul (plasat ultima)
- 5/6/7: efectuarea operațiunilor ecx, valoarea în modificările ecx
- 8: extragerea valorii din stivă în ebx: ebx va deveni 200 (ultima locație, prima extragere)
- 9: extragerea valorii din stivă în ecx: ecx va deveni din nou 100 (prima locație, ultima extragere)
Pentru a afla ce se întâmplă în memorie, când plasați și extrageți valori pe stivă, consultați figura de mai jos:
(stiva de aici este plina de zerouri, dar in realitate nu este la fel ca aici). ESP se află în locul în care acesta indică)
O notă importantă: registrul eax este aproape întotdeauna folosit pentru a stoca rezultatul procedurii.
Acest lucru se aplică și funcțiilor ferestrelor. Desigur, puteți folosi orice alt registru în procedurile proprii, dar acesta este standard.
Așa că următoarea lecție sa încheiat. În următoarea lecție vom scrie primul program în asamblare.
Aproximativ 0 la începutul numerelor hexazecimale. Asta este scris pe acest subiect în Zubkov ( „asamblare pentru DOS, Windows și Unix“, 1.2.3 hexazecimal.):
Programele de asamblare pentru numerele de înregistrare încep cu A, B, C, D, E, F, la început atribuite la „0“ pentru a evita confuzia cu un nume de variabilă număr, sau alt identificator. După numerele hexazecimale, litera "h"