[Assembler][AT&T][Intel IA-32] Potrzebna pomoc z inkrementacją

0

Cześć, mam stosunkowo prosty problem, ale nie potrafię znaleźć rozwiązania.

Próbuję napisać program sumujący dwie liczby z pamięci, kawałek (32bit) po kawałku (z przeniesieniem). Niestety, nie do końca rozumiem czemu, licznik pętli nie zwiększa się z kolejnymi operacjami "inc".

Program pod architekturę Intela, ze składnią AT&T

.code32
 
SYSEXIT = 1
EXIT_SUCCESS = 0
SYSWRITE = 4
STDOUT = 1
SYSREAD = 3
STDIN = 0
 
 
.align 32
.data
liczba1:
    .long 0xF0000111, 0x000B0000
# .long A1, A2
liczba2:
    .long 0x10000333, 0x000A000F
# .long B1, B2
rozmiar:
    .long 0x00000002
 
#Cel: wrzucenie na stos kolejno: A1+B1, A2+B2, +ewentualne "1" z przeniesienia

.text
.global _start
_start:
mov $0, %ecx                    #inicjalizacja licznika
movl rozmiar(,%ecx,4), %edi     #przeniesienie rozmiaru do %edi (ilosc obrotow petli)
 
addition:
movl liczba1(,%ecx,4), %eax     #przeniesienie 32bit kawalka liczby
movl liczba2(,%ecx,4), %ebx    
 
adcl %ebx, %eax                 #dodawanie
push %eax                       wrzucenie wyniku na stacka
 
inc %ecx                        #inkrementacja licznika
cmp %edi, %ecx                  #porownanie rozmiaru (2) z licznikiem
je overflow                     # if %edi == %ecx
jmp addition                    # else powrot do petli
 
# ostatnia suma (==1) w przypadku gdy nastapilo przepelnienie po ostatnim dodawaniu w petli,
# lub wrzucenie 0 na stacka
overflow:   
mov $0, %eax                   
adcl $0, %eax
push %eax
 
koniec:
mov $SYSEXIT, %eax
mov $EXIT_SUCCESS, %ebx
int $0x80

Jeżeli ktoś przy okazji też wyjaśnił co robić/czego nie robić następnym razem korzystając z inc i w razie czego wskazał inne błędy to byłbym wdzięczny. Z góry dzięki za pomoc

0

Nie nadpisujesz przypadkiem w tym miejscu rejestru ecx?

movl liczba1(,%ecx,4), %eax     #przeniesienie 32bit kawalka liczby
movl liczba2(,%ecx,4), %ebx    

W ogóle dlaczego wybrałeś AT&T składnie, jak intela jest czytelniejsza.

W ogóle odpal to w debugerze i podglądnij zawartość rejestrów, może coś przeoczyłeś.
Pierwszy cel to w pętli sprawdź jak wygląda ecx.

0

Niestety nie mam wyboru co do składni

Nie wydaje mi się żebym nadpisywał, bo to jest jedynie offset przy adresacji

Tak wygląda adresacja przy mov
segment:displacement(base register, offset register, scalar multiplier)

I wtedy:
movl liczba1(,%ecx,4), %eax

oznacza przeniesienie z pod adresu liczba1 + 4bajty * wartość %ecx

Sprawdziłem wartość %ecx po każdej linijce gdzie był wykorzystywany, od początkowego przypisania ==0 nic się nie zmienia, zaraz po inc %ecx też jest zero.

0

może spróbuj pozamieniac rejestry ecx na ebx, a ebx na ecx

Niestety nie pomogło, dalej licznik wisi na zerze i pętla wykonuje się (prawie) nieskończenie, do zapisania całego stosu i wysypania Segmentation fault..

0

spróbuj dać zamiast inc reg add 1, reg, z tego co myślę w at&t jest odwrotnie niż w intelu.

Zrób kilka printów, dbg odpal.

Ogólnie inc powinno działać, jak u ciebie nie działa, to wiedz, że coś się dzieje.

Tej składni nie znam zbytnio, nawet nie chcę jej rozumieć, nie lubię jej.

Wydziel części kodu do innego pliku i sprawdzaj je po kolej.
Nawet poszczególne instrukcje, czy działają.

0

Wszystkie instrukcje działają poza inc właśnie. Najlepsze jest to, że w innym programie inkrementacja normalnie działa, a nie jest używana w jakiś inny sposób. O ile add $1, %ecx działa to niestety add ustawia flagę CF na 0, a jest mi ona potrzebna do zarządzania przeniesieniami przy adcl, inaczej, wiadomo, wyniki nie będą się zgadzały przy przepełnieniu.

0

Po paru godzinach prób i błędów udało się rozwiązać, wystarczyło wywalić .code 32 z 1. linii, co potem wywalało błąd operand mismatch for 'push', a to z kolei można było naprawić zastępując %eax na %rax przy obydwu push %eax. Dzięki za pomoc.

/thread

1 użytkowników online, w tym zalogowanych: 0, gości: 1