Witam,
próbuję wczytywać liczbę z konsoli i konwertować ją od razu na system dziesiątkowy (po wczytaniu jest to łańcuch ASCII). Po licznych niepowodzeniach postanowiłem zrozumieć kod napisany przez kogoś innego. Funkcja prezentuje się następująco:
read_value:
mov eax, 0
push eax
read_value_loop:
mov eax, 03h
mov ebx, 0
mov ecx, tmp
mov edx, 1
int 80h
mov eax, [tmp]
cmp eax, 48
jl read_end_loop
cmp eax, 58
jge read_end_loop
sub eax, 48
pop ebx
imul ebx, 10
add eax, ebx
push eax
jmp read_value_loop
Program rzeczywiście wczytuje liczbę, lecz pozostawia sporo wątpliwości. Wykonując program pod linuksem ./nazwa działa dobrze, lecz korzystając z debuggera gdb i iterując po każdej instrukcji (nexti) funkcja zapętla się proponując użytkownikowi wprowadzanie tekstu nieskończoną ilość razy.
Prosiłbym o pomoc w zrozumieniu kodu.
Oto jak go rozumiem do tej pory.
Po odłożeniu 0 na stos, ustawiamy odpowiednie rejestry w taki sposób aby program obsługi przerwania wczytał tekst z konsoli. Następnie generujemy przerwanie (int 80h). Do rejestru EAX przesyłamy (i tu moja pierwsza wątpliwość) pierwszy znak z wczytywanego tekstu. Wiemy, że cyfry w ASCII są liczbami od 48 do 57, więc używająć cmp sprawdzamy czy rzeczywiście odczytana cyfra to cyfra, a nie litera. Jeśli tak nie jest to skaczemy do początku i ponownie odczytujemy tekst. Natomiast jeśli tak jest to odejmując od wczytanej cyfry 48 uzyskujemy cyfrę w systemie decymalnym. Pobieramy ze stosu liczbę oznaczając ilość iteracji w tej pętli i mnożymy razy 10, dodając do odczytanej cyfry. Odkładamy naszą aktualną wartość na stos i ... skaczemy znowu do początku by odczytać liczbę? Tak to wygląda w debuggerze, a jednak uruchamiając program normalnie ( ./ ) program działa prawidłowo.
Dlaczego tak się dzieje?