Asembler x86/Jak używać debuggera ALD: Różnice pomiędzy wersjami
Usunięta treść Dodana treść
{{Spis treści}} |
optymalizacja |
||
Linia 209:
xorl %edx,%edx
N1:
push %ebx
shrl %ebx,%eax
addl $48,%ecx▼
andl %ebx,(%esp)
pop %ebx
decl %ecx
movl %ecx($msg),%dl
jnz N1
Linia 230 ⟶ 233:
</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
Program nie miał wykonywać żadnych operacji
▲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>
</source>
Linia 265 ⟶ 262:
# 0804809A BB0A000000 mov ebx, 0xa
# 0804809F B90A000000 mov ecx, 0xa
# 080480A4 31D2 xor edx, edx
# ... # 080480A6:<N1> F7F3
# ... # 080480A8 81C230000000
# 080480AE 49 dec ecx
# 080480AF 8891D8900408 mov byte [ecx+0x80490d8], dl
# 080480B5 81F900000000
# 080480BB 75E9 jne +0xe9 (0x80481a6)
# 080480BD B804000000 mov eax, 0x4
Linia 310 ⟶ 309:
# 080480A6:<N1> F7F3
</source>
Przede wszystkim interesują nas zawartości rejestrów EAX
<source lang=bash>
Linia 325 ⟶ 324:
# 080480A8 81C230000000
</source>
<source lang=bash>
Linia 341 ⟶ 340:
# 080480A6:<N1> F7F3
</source>
Na pierwszy rzut oka tym razem również wszystko jest w porządku. Jednak po wnikliwej analizie zawartości rejestrów zauważymy, że w rejestrze EDX znajdują się pozostałości z poprzedniego obiegu pętli. Aby uniknąć błędnych wyników, należy poprawić kod tak, aby zerowanie rejestru EDX przeprowadzać na początku każdego obiegu pętli przed wykonaniem operacji dzielenia. Spróbujemy mimo wszystko kontynuować działanie programu krok po kroku
Widzimy, że operacja przesunięcia nie została wykonana.
Po wprowadzeniu stosownych poprawek prawidłowy kod źródłowy będzie miał postać:
Linia 399 ⟶ 377:
N1:
xorl %edx,%edx
pushl %ebx
andl %ebx, (%esp)
popl %ebx
orl $48,%edx
decl %ecx
movl %ecx(%msg),%eax
jnz N1
|