This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
bune-practici [2015/11/30 16:49] catalin.vasile3004 [Segmentation Fault debugging: GDB quicky] |
bune-practici [2015/11/30 21:08] (current) catalin.vasile3004 [Încărcarea datelor în registre] |
||
---|---|---|---|
Line 78: | Line 78: | ||
Deşi **nr** are valoarea 23, programul afişează **number: 1836412439**.\\ | 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**. | 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> | + | <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ă 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. | O primă încercare de a rezolva problema ar fi să încercăm să-l aducem pe **nr** direct într-un registru de 1 byte. | ||
Line 234: | Line 234: | ||
</code> | </code> | ||
Pentru a vedea ce instrucţiunea a provocat segfault, putem da următoarea comandă: | Pentru a vedea ce instrucţiunea a provocat segfault, putem da următoarea comandă: | ||
- | <code> | + | <code bash> |
(gdb) display/10i $pc | (gdb) display/10i $pc | ||
1: x/10i $pc | 1: x/10i $pc | ||
Line 251: | Line 251: | ||
* **display** face dump de la un pointer dat ca argument, în cazul nostru **$pc** | * **display** face dump de la un pointer dat ca argument, în cazul nostru **$pc** | ||
* **i**-ul îi spune lui **display** să interpreteze datele de acolo ca şi cum ar fi instrucţiuni | * **i**-ul îi spune lui **display** să interpreteze datele de acolo ca şi cum ar fi instrucţiuni | ||
- | * **10** îi sune lui **display** câţi operanzi/instrucţiuni de tipul **i** (instrucţiune) să afişeze\\ \\ | + | * **10** îi spune lui **display** câţi operanzi de tipul **i** (instrucţiune) să afişeze\\ \\ |
Prin ''<keep_printing+some_number>'', **gdb** incearcă să ne arate cam pe unde ar fi această instrucţiune. În cazul nostru instrucţiunea este aproape de label-ul **keep_printing**.\\ | Prin ''<keep_printing+some_number>'', **gdb** incearcă să ne arate cam pe unde ar fi această instrucţiune. În cazul nostru instrucţiunea este aproape de label-ul **keep_printing**.\\ | ||
Pentru a vedea ce valoare a avut un registru la momentul în care s-a declanşat **segfault**-ul, puteţi da: | Pentru a vedea ce valoare a avut un registru la momentul în care s-a declanşat **segfault**-ul, puteţi da: |