User Tools

Site Tools


bune-practici

This is an old revision of the document!


A PCRE internal error occured. This might be caused by a faulty plugin

====== Bune practici ====== Mai jos găsiți un ghid bune practici, recomandări și greșeli frecvente care apar în momentul în care lucrați în limbajul de asamblare. Să țineți cont, vă rugăm, de acestea în momentul în care lucrați în laboratoare sau teme de casă. ===== Exemple ===== * Program care afișează ''%%"Hello, World!"%%'' folosind asamblare cu NASM în linia de comandă (x86, 32 de biți) * https://gist.github.com/razvand/782d6471f23352300f11 * Program care afișează ''%%"Hello, World!"%%'' folosind asamblare cu NASM în linia de comandă (x86, 64 de biți) * https://gist.github.com/razvand/49aa3bbc13ee29f4f46b * Program care apelează funcții externe pe Windows (x86, 32 de biți) * https://gist.github.com/razvand/a9dbb356d2344723408c * Program care apelează funcții externe pe Linux (x86, 32 de biți) * https://gist.github.com/razvand/65dc30fbb64b37f4d617 ===== Erori des întâlnite ===== ==== Încărcarea datelor în registre ==== Adesea apar erori chiar la încărcarea datelor în registre. <file asm load.asm> extern printf section .data nr: DB 23 str: DB 'number: %d', 0 section .text global main main: mov eax, [nr] push eax push str call printf add esp, 8 ret </file> În momentul în care se face ''mov eax, [nr]'', instrucţiunea **mov** încearcă să deducă dimensiunea mutării (câte date/bytes să ia de la adresa de la care începe **nr**?). **nr** fiind doar o adresă în memorie, nu-i spune nimica compilatorului. Din acest motiv, compilatorul încearcă să se uite dacă nu cumva în această instrucţiune nu există şi un registru implicat. Îl vede pe **eax**. În consecinţă, compilatorul va codifica instrucţiunea astfel încât în **eax** să se aducă sizeof(eax) (adică 4 bytes) de la adresa lui **nr**.\\ Deşi **nr** are valoarea 23, programul afişează **number: 1836412439**.\\ De ce? Pentru că la **nr** find un singur byte, procesorul continuă să aducă din memorie încă 3 bytes astfel încât să îl poate umple pe **eax**. În cazul nostru, după **nr**, în memorie, este declarat vectorul **str**, aşa că va lua încă 3 bytes de la el pentru a-l umple pe **eax**. <note important>Intuitiv, v-aţi aştepta ca asamblorul/compilatorul să urle la voi "că uite domne, eu am declarat variabila de 1 byte, şi am scris din greşeală că vreau să aduc 4 bytes de acolo. Ca şi în cazul limbajului **C**, limbajul de asamblare te lasă să te împuşti singur în picior. Nu este treaba lui să facă check-uri. Dacă tu vrei **1 milion de bytes** de la adresa **0xB00B5**, el o să-ţi codifice programul în binar astfel încât să-ţi aducă date de la adresa **0xB00B5**. Că după îţi bubuie programul în faţă cu un **Segmentation Fault** pentru că ai încercat să accesezi o zonă de memorie care nu ţi-a fost alocată, e deja treaba sistemului de operare şi a procesorului.</note> === O primă rezolvare === O primă încercare de a rezolva problema ar fi să încercăm să-l aducem pe **nr** direct într-un registru de 1 byte. <file asm load_byte.asm> extern printf section .data nr: DB 23 str: DB 'number: %d', 0 section .text global main main: mov al, [nr] ; modified line push eax push str call printf add esp, 8 ret </file> Mie, personal, s-a întâmplat ca acum să-mi dea corect afişarea. Dar programul nu este încă corect. Noi îi transmitem lui **printf** să afişeze un număr reprezentat pe 4 bytes. Deşi noi am încărcat datele în **al**, noi îi spunem lui **printf** să afişeze conţinutul la tot **eax**, nu doar la **al**. În unele cazuri, s-ar putea ca conţinutul părţii superioare a lui **eax** să nu fie curat, din cauza codului care s-a executat anterior. S-ar putea ca cei mai semnificativi 3 bytes să fie plini cu garbage (date random), şi afişarea noastră tot să nu fie corectă. Astfel că mai este nevoie de încă o corectură: <file asm load_byte.asm> extern printf section .data nr: DB 23 str: DB 'number: %d', 0 section .text global main main: xor eax, eax ; eax = 0 mov al, [nr] ; modified line push eax push str call printf add esp, 8 ret </file> Tot registrul **eax** trebuie iniţializat la **0**, ca să fim singuri că nu există junk în partea superioară. ===== Categorie 3 ===== * TODO * TODO

bune-practici.1448888525.txt.gz · Last modified: 2015/11/30 15:02 by catalin.vasile3004