Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen gezeigt.

Link zu dieser Vergleichsansicht

tux:debug_hello_world [2011/10/09 14:34]
wikisysop [Disassemble Binary]
tux:debug_hello_world [2011/10/10 15:13] (aktuell)
wikisysop [Disassemble Binary]
Zeile 1: Zeile 1:
 [[:tux|{{ :​linux.png?​40|}}]] [[:tux|{{ :​linux.png?​40|}}]]
-===== "Hello, world" im Debugger =====+===== "​Hello ​World!" im Debugger =====
  
 Das Debuggen eines Programms gehört sicherlich zu den anspruchsvollsten Angelegenheiten,​ kann aber unter gegebenen Umständen äußerst nützlich sein.  Das Debuggen eines Programms gehört sicherlich zu den anspruchsvollsten Angelegenheiten,​ kann aber unter gegebenen Umständen äußerst nützlich sein. 
Zeile 69: Zeile 69:
 End of assembler dump.</​xterm>​ End of assembler dump.</​xterm>​
  
-<​xterm><​fc #​800000>​(gdb)</​fc><​fc #​008000>​break main</​fc>​+<​xterm><​fc #​800000>​(gdb)</​fc>​ <fc #​008000>​break main</​fc>​
 Breakpoint 1 at 0x80483bd: file firstprog.c,​ line 6.</​xterm>​ Breakpoint 1 at 0x80483bd: file firstprog.c,​ line 6.</​xterm>​
  
Zeile 166: Zeile 166:
 Nicht weiter von Belang aber die mov-Instruktion möchte die Adresse >><​fc #​FF00FF>​0x80484b0</​fc><<​ dort hin schreiben. Aber warum? Was ist so besonders an der Speicheradresse >><​fc #​FF00FF>​0x80484b0</​fc><<?​ Finden wir es raus und lassen wir uns mal die ersten 8 Byte dieser Adresse anzeigen: Nicht weiter von Belang aber die mov-Instruktion möchte die Adresse >><​fc #​FF00FF>​0x80484b0</​fc><<​ dort hin schreiben. Aber warum? Was ist so besonders an der Speicheradresse >><​fc #​FF00FF>​0x80484b0</​fc><<?​ Finden wir es raus und lassen wir uns mal die ersten 8 Byte dieser Adresse anzeigen:
  
-<​xterm><​fc #​800000>​(gdb)</​fc> ​(gdb) <fc #​008000>​x/​8xb 0x80484b0</​fc>​+<​xterm><​fc #​800000>​(gdb)</​fc>​ <fc #​008000>​x/​8xb 0x80484b0</​fc>​
 <fc #​FF00FF>​0x80484b0</​fc>:​ 0x48 0x65 0x6c 0x6c 0x6f 0x20 0x57 0x6f</​xterm>​ <fc #​FF00FF>​0x80484b0</​fc>:​ 0x48 0x65 0x6c 0x6c 0x6f 0x20 0x57 0x6f</​xterm>​
  
Zeile 242: Zeile 242:
 <fc #​800000>​(gdb)</​fc>​ <fc #​008000>​x/​4xb $esp + 0x1c</​fc>​ <fc #​800000>​(gdb)</​fc>​ <fc #​008000>​x/​4xb $esp + 0x1c</​fc>​
 0xbffff6fc:​ 0x02 0x00 0x00 0x00 0xbffff6fc:​ 0x02 0x00 0x00 0x00
-//<fc #​800000>​(gdb)</​fc>​ <fc #008000>x/i $eip</​fc>​ +//<fc #​808080>​(gdb)x/​i $eip 
-<fc #​0000FF>​=>​ 0x80483d8 <​main+36>:​ cmp ​   DWORD PTR [esp+0x1c],​0x9</​fc>​ +=> 0x80483d8 <​main+36>:​ cmp ​   DWORD PTR [esp+0x1c],​0x9 
-<fc #​800000>​(gdb)</​fc>//</​xterm>​+(gdb)</​fc>//</​xterm>​ 
 + 
 +Schauen wir uns nun noch einmal das gesamte Disassembling an, kann der Verlauf der Schleife bzw. der gesamte Programmverlauf nachvollzogen werden: 
 + 
 +<​xterm>​<fc #​800000>​(gdb)</​fc>​ <fc #008000>disassemble main</fc> 
 +Dump of assembler code for function main: 
 +   //​0x080483b4 <​+0>:​ push ​  ebp 
 +   ​0x080483b5 <​+1>:​ mov ​   ebp,esp 
 +   ​0x080483b7 <​+3>:​ and ​   esp,​0xfffffff0 
 +   ​0x080483ba <​+6>:​ sub ​   esp,​0x20//​ 
 +   <​fc #​008080>​0x080483bd <​+9>:​ mov ​   DWORD PTR [esp+0x1c],​0x0</​fc>​ 
 +   <​fc #​FF00FF>​0x080483c5 <​+17>:​ jmp ​   0x80483d8 <​main+36></​fc>​ 
 + ⇓ <fc #​0000FF>​0x080483c7 <​+19>:​ mov ​   DWORD PTR [esp],​0x80484b0 
 +   ​0x080483ce <​+26>:​ call ​  ​0x80482f0 <​puts@plt>​ 
 +   ​0x080483d3 <​+31>:​ add ​   DWORD PTR [esp+0x1c],​0x1 
 +   ​0x080483d8 <​+36>:​ cmp ​   DWORD PTR [esp+0x1c],​0x9 
 +   ​0x080483dd <​+41>:​ jle ​   0x80483c7 <​main+19></​fc>​ 
 +   ​0x080483df <​+43>:​ leave ​  
 +   ​0x080483e0 <​+44>:​ ret ​    
 +End of assembler dump.</​xterm>​ 
 + 
 +Die dunklegrün markierte Zeile mit der ersten >><​fc #​008080>​mov</​fc><<​-Instruktion initialisiert die Variable >><​fc #008080>i</​fc>​<< und belegt diese mit >><​fc #​008080>​0x0</​fc><<,​ die pink markierte Zeile mit der >><​fc #​FF00FF>​jmp</​fc><<​-Instruktion springt in die Schleife zur >><​fc #​0000FF>​cmp</​fc><<​-Instruktion und die blau markierten Zeilen repräsentieren die eigentliche >><​fc #​FF0000>​for()</​fc><<​-Schleife in dem zuerst verglichen wird >><​fc #​0000FF>​cmp</​fc><<​ und solange das Ergebnis dieses Vergleichs ≤ 9 ist >><​fc #​0000FF>​jle</​fc><<​ der Instruktion Pointer >>​EIP<<​ zur zweiten >><​fc #​0000FF>​mov</​fc><<​-Instruktion springt, wo die Adresse >>​0x80484b0<<​ in >>​ESP<<​ geschrieben wird (Wir erinnern uns, in dieser Adresse ist der String >>"​Hello World!<<​ gespeichert),​ danach springt >>​EIP<<​ weiter an die nächste Adresse mit der >><​fc #​0000FF>​call</​fc><<​-Instruktion,​ welche den in ESP gespeicherten String >>"​Hello World!"<<​ ausgibt. >>​EIP<<​ springt nun weiter zu >><​fc #​0000FF>​add</​fc><<​-Instruktion,​ wo >><​fc #​0000FF>​0x1</​fc><<​ zu der Adresse >>​[esp+0x1c]<<​ hinzu addiert wird und der Vergleich dieser Adresse mit ≤ 9 wird erneut durchgeführt. 
 + 
 +Der Vollständigkeit wegen sollte noch gezeigt werden, dass die Schleife auch wie vorgesehen verlassen (>><fc #0000FF>leave</​fc><<​) wird, wenn die Variable >>​i<<​ den Wert >><​fc #​FF0000>​0xa</​fc><<​ (10<​sub>​10</​sub>​) erreicht hat: 
 + 
 +<​xterm><​fc #​800000>​(gdb)</​fc>​ <fc #​008000>​x/​4xb $esp + 0x1c</​fc>​ 
 +0xbffff6fc:​ <​fc #​FF0000>​0x0a</​fc>​ 0x00 0x00 0x00 
 +(gdb) x/i $eip 
 +=> 0x80483d8 <​main+36>:​ cmp ​   DWORD PTR [esp+0x1c],​0x9 
 +<fc #​800000>​(gdb)</​fc> ​nexti 
 +0x080483dd 6  ​ for(i=0; i < 10; i++) 
 +<fc #​800000>​(gdb)</​fc> ​<fc #​008000>​x/i $eip</fc> 
 +=> 0x80483dd <​main+41>:​ jle ​   0x80483c7 <​main+19>​ 
 +<fc #​800000>​(gdb)</​fc>​ <fc #​008000>​nexti</​fc>​ 
 +<fc #​0000FF>​10 }</​fc>​ 
 +<fc #​800000>​(gdb)</​fc>​ x/i $eip 
 +=> 0x80483df <​main+43>:​ <​fc #​0000FF>​leave</​fc> ​  
 +<fc #​800000>​(gdb)</​fc>​</​xterm>​ 
 + 
 +Mächtig viel Zenober für ein Programm, welches in gerade mal 2 Millisekunden vom Prozessor ausgeführt wird. Ich habe ein ganzes Wochenende mit diesem Artikel verbracht, habe aber viel dabei gelernt ;-) 
 + 
 +<​xterm>​$ <fc #​008000>​time ./​a.out</​fc>​  
 +Hello World! 
 +Hello World! 
 +Hello World! 
 +Hello World! 
 +Hello World! 
 +Hello World! 
 +Hello World! 
 +Hello World! 
 +Hello World! 
 +Hello World! 
 + 
 +real 0m0.002s 
 +user 0m0.000s 
 +sys 0m0.000s</​xterm>​ 
 + 
 + --- //pronto 2011/10/09 15:21//
tux/debug_hello_world.1318163647.txt.gz (9545 views) · Zuletzt geändert: 2011/10/09 14:34 von wikisysop
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0