Prosty program w Assemblerze pod Linuksa

Wiec reasumując… program który rozwiąże moje zadanie wyglądał by tak:

.text

.global _start:


funkcja:

sub %ecx,%ebx

mov %ebx,%eax

mul %edx

ret


_start:

mov $2, %ebx

mov $4, %ecx

mov $6, %edx

xor %eax, %eax

call funkcja

nop

Zapomniałeś o wartości bezwzględnej. No i wciąż nie wiem co masz zamiar zrobić, kiedy wynik nie zmieści się w eax…

Tzn. to co miałem w poprzednim programie ?

cmp $0, %eax

jge end_if

neg %edx

end_if:

Jeśli tak to czy mógł bym Ciebie prosić o to byś to mi wyjaśnił w skrócie ? Bo tego to ja nie rozumiem za nic :frowning:

Wyjaśnię o co chodzi, ale czy działa czy nie i dlaczego musisz wykombinować samemu.

cmp porównuje dwa operandy. Tutaj porównujesz zero ($0) i wartość z eax. Porównanie nie zmienia rejestrów, których normalnie używasz (eax, ebx,…) i jedynie ustawia wartość w rejestrze flag. Rejestr flag to takie miejsce, z którego można odczytać ciekawe informacje na temat ostatniej operacji. Np. po operacji porównania można się dowiedzieć jaki był jej wynik. Najczęściej wtedy wykonuje się skok warunkowy.

Czyli: cmp porównuje dwie wartości, ale żeby coś z nimi zrobić, potrzebujesz kolejnej instrukcji, która na wynik porównania zareaguje. Tutaj instrukcją jest jge. jge to skok warunkowy, oznacza on “jump if greater or equal” czyli skocz, jeśli większe lub równe. Efektywnie zatem cmp i jge sprawdzają relację między dwoma argumentami przy cmp. Jeśli eax >= 0 to…

Argument przy jge mówi Ci dokąd skoczyć, jeśi warunek jest prawdziwy. Czyli jeśli eax >= 0 to nastąpi skok do end_if. W praktyce oznacza to, że jeśli warunek jest prawdziwy, kod pomiędzy jge a etykietą skoku (end_if:) zostanie pominięty i wykona się kod zaraz za end_if. Co jeśli warunej nie jest prawdziwy? jge nie wykonani skoku i wykona się kod za jge, czyli w tym wypadku neg.

Z kolei neg zamienia wartość w rejestrze na przeciwną (4 na -4, -100 na 100, itd.)

Przeanalizuje ten kawałek, gdzie on pasuje do tego co masz teraz i na jakich rejestrach powinien operować.