Asembler x86/Jak używać debuggera ALD: Różnice pomiędzy wersjami

Usunięta treść Dodana treść
DrJolo (dyskusja | edycje)
DrJolo (dyskusja | edycje)
Linia 186:
global _start
_start:
mov eax,0xffff0x0007
call _printEAXdecimal
Linia 229:
pop edx
ret
</source>
 
Na pierwszy rzut oka wszystko wydaje się być w porządku. Kompilacja wraz z linkowaniem przebiegła pomyślnie. Próba wykonania programu daje jednak poniższy wynik:
 
<source lang=bash>
user@myhost:~$ ./decimalPrint
Floating point exception
user@myhost:~$
</source>
 
Program nie miał wykonywać żadnych operacji zmiennoprzecinkowych. Przypuszczamy jednak, że problem może mieć miejsce w wierszu, w którym wykonujemy operację dzielenia całkowitego:
 
<source lang=asm>
div ebx
</source>
 
Chcielibyśmy zatem wstrzymać działanie programu tuż przed wykonaniem tej operacji, by dokładnie sprawdzić argumenty instrukcji oraz wynik jej działania. W tym celu uruchamiamy debugger poleceniem:
 
<source lang=text>
user@myhost:~$ ald decimalPrint
Assembly Language Debugger 0.1.7
Copyright (C) 2000-2004 Patrick Alken
 
decimalPrint: ELF Intel 80386 (32 bit), LSB - little endian, Executable, Version 1 (Current)
Loading debugging symbols...(11 symbols loaded)
ald>
</source>
 
Następnie przeprowadzamy deasemblację (klawisz '''d''' i '''ENTER''') w celu poznania adresu wskaźnika do interesującej na instrukcji:
 
<source lang=text>
ald> d
08048080:<_start> B807000000 mov eax, 0x7
08048085 E80C000000 call near +0xc (0x8048096:_printEAXdecimal)
0804808A B801000000 mov eax, 0x1
0804808F BB05000000 mov ebx, 0x5
08048094 CD80 int 0x80
08048096:<_printEAXdecimal> 52 push edx
08048097 51 push ecx
08048098 53 push ebx
08048099 50 push eax
0804809A BB0A000000 mov ebx, 0xa
0804809F B90A000000 mov ecx, 0xa
080480A4 31D2 xor edx, edx
080480A6:<N1> F7F3 div ebx
080480A8 81C230000000 add edx, 0x30
080480AE 49 dec ecx
080480AF 8891D8900408 mov byte [ecx+0x80490d8], dl
080480B5 81F900000000 cmp ecx, 0x0
080480BB 75E9 jne +0xe9 (0x80481a6)
080480BD B804000000 mov eax, 0x4
080480C2 BB01000000 mov ebx, 0x1
080480C7 B9D8900408 mov ecx, 0x80490d8
080480CC BA0A000000 mov edx, 0xa
080480D1 CD80 int 0x80
080480D3 58 pop eax
Hit <return> to continue, or <q> to quit
</source>
 
Naciskamy klawisz '''q''' oraz '''ENTER''', by nie wyświetlać dalszych obszarów pamięci. Szukany adres to ''0x080480A6''. Trzeba zatem pod wskazanym adresem ustawić pułapkę. Do tego celu służy polecenie '''break''':
 
<source lang=text>
ald> break 0x080480a6
Breakpoint 1 set for 0x080480A6
ald>
</source>
 
Dla pewności możemy wyświetlić wszystkie zdefiniowane pułapki, aby mieć pewność, czy program nie będzie dodatkowo wstrzymany w żadnym innym miejscu. Do tego celu służy polecenie '''lbreak''':
 
<source lang=text>
ald> lbreak
Num Type Enabled Address IgnoreCount HitCount
1 Breakpoint y 0x080480A6 none 0 (N1+0x0)
ald>
</source>
 
Jeśli wszystko się zgadza, możemy uruchomić program poleceniem '''run''':
 
<source lang=text>
ald> run
Starting program: decimalPrint
Breakpoint 1 encountered at 0x080480A6
eax = 0x00000007 ebx = 0x0000000A ecx = 0x0000000A edx = 0x00000000
esp = 0xBFC9251C ebp = 0x00000000 esi = 0x00000000 edi = 0x00000000
ds = 0x007B es = 0x007B fs = 0x0000 gs = 0x0000
ss = 0x007B cs = 0x0073 eip = 0x080480A6 eflags = 0x00000246
 
Flags: PF ZF IF
 
 
080480A6:<N1> F7F3 div ebx
ald>
</source>