Witam, zaczynam dopiero swoją przygodę z asemblerem, rozumiem już trochę podstaw programowania w tym języku, ale mam obecnie problem z programem którego nie umiem przeskoczyć(i jestem pewien że to czego nie widzę jest banalne). Programuję pod Linuxem w składni AT&T(wymóg kursu). Program który robię dla wprawki ma następujące zadanie - realizacja dodawania, odejmowania i mnożenia w naturalnym binarnym/U2 na dwóch liczbach pobranych ze standardowego wejścia. Liczby te mają mieć dowolną długość(nawet do kilku tysięcy bitów).
Mój kod(oczywiście jest jeszcze nieskończony, zaciąłem się i nie widzę sensu w dalszym pisaniu dopóki nie zrozumiem co robię źle):
SYSEXIT = 1
SYSREAD =3
SYSWRITE = 4
STDOUT =1
STDIN =0
EXIT_SUCCESS = 0
.align 32
.section .data
podaj_ciag: .ascii "Podaj pierwszą liczbę: \n"
podaj_ciag_dl = . - podaj_ciag
podaj_druga: .ascii "\nPodaj drugą liczbę: \n"
podaj_druga_dl = . - podaj_druga
.lcomm znak, 1
ile_znakow: .long 0
pierwsza_liczba: .long 0
.section .text
.global _start
_start:
mov $SYSWRITE, %eax
mov $STDOUT, %ebx
mov $podaj_ciag, %ecx
mov $podaj_ciag_dl, %edx
int $0x80
jmp petla
petla:
mov $SYSREAD, %eax
mov $STDIN, %ebx
mov $znak, %ecx # pobieramy znak i zapisujemy go w pamięci
mov $1, %edx
int $0x80
cmpb $0xA, (%ecx) #warunek końca, znak enter kończy pobieranie znaków
je druga_liczba #skok do etykiety w której zajmę się drugą liczbą, tego fragmentu jeszcze nie ruszyłem
cmpb $0x30, (%ecx)
jb petla #znak nie jest cyfrą, pobieramy następny
cmpb $0x39, (%ecx)
ja petla #znak nie jest cyfrą, pobieramy następny
#pobrany znak jest cyfrą
incl ile_znakow #załóżmy że działa
xor %eax, %eax
mov $10, %eax
mull (%ecx)
add %eax, pierwsza_liczba #4 powyższe linijki mają wziąć pojedyncze znaki, mnożyć i dodawać w celu otrzymania spójnej liczby dziestnej
push (%ecx) #wrzucamy pobrany znak na stos(póki co bez celu, pracowałem na różnymi rozwiązaniami)
mov $SYSWRITE, %eax
mov $STDOUT, %ebx
mov $znak, %ecx #wyprowadzenie ciągu na ekran
mov $1, %edx
int $0x80
jmp petla #skok do początku sekwencji w celu pobrania następnego znaku
druga_liczba:
mov $SYSWRITE, %eax
mov $STDOUT, %ebx
mov $podaj_druga, %ecx
mov $podaj_druga_dl, %edx
int $0x80
jmp koniec
koniec:
mov $SYSWRITE, %eax
mov $STDOUT, %ebx
movl $pierwsza_liczba, %ecx #wyprowadzenie na ekran całej liczby
mov $32, %edx
int $0x80
mov $SYSEXIT, %eax
mov $EXIT_SUCCESS, %ebx
int $0x80
Z czym mam problem - aby pobrać całą liczbę z klawiatury pobieram pojedyncze znaki po kolei. Przy tej operacji początkowo chciałem zliczać pobrane znaki w 'zmiennej' ile_znakow. No i niby się to wszystko inkrementuje(incl ile_znakow), ale przy próbie wyprowadzenia wartości symbolu na ekran albo nic się nie pojawia, albo są jakieś dziwne znaczki i nie wiem dlaczego.
Drugi problem związany z pierwszym - pobieram te znaki, próbuję je zapisać jako całą liczbę(czyli pętla z mnożeniem przez 10 i dodawaniem). Wynik chciałem zapisać pod adresem pierwsza_liczba, coś się niby zapisuje ale przy wyprowadzaniu na ekran jest identyczny problem jak powyżej - nic się nie wyświetla, lub wyświetlają się jakieś dziwne znaczki.
Trzeci problem, w zasadzie pytanie - w dokumentacji do as'a znalazłem informacje że domyślnie wszystkie wprowadzane znaki są interpretowane jako cyfry dziesiętne, jednak próba użycia cmpb w celu porównania kodów ascii wymaga ode mnie użycia numeru ascii w postaci szesnastkowej, a nie dziesiętnej. Dlaczego?
Domyślam się że powyższy kod jest tragiczny, ale to jedyny sposób jaki znam, a i tak nie działa. Jestem otwarty na wszystkie porady i uwagi.
dodałem code=asm - msm