Hello.
I created this program in x32 version of Ubuntu in asm. It worked okay and recently I installed x64 version of ubuntu and I also installed gcc-multilib so i can run 32 bit code in x64 ubuntu.
I create a modul with gcc -Program.o -o Program -m32.
For some reason, this assignment which lists all numbers between 1 and N that are divisible by 11, doesnt work anymore. Everything worked fine before, but now under x64 it throws floating point exception.
Here is my program. Are there problems with registers that I am using?
Please help me find the mistake, thank you.
PS: Don't mind the comments, they are in our language
Code:
bits 32 ; Delamo v 32 bitnem okolju.
global main ; Programsko okolje.
extern printf, scanf ; Printf izpisujemo na zaslon, scanf pa beremo z tipkovnice.
section .bss ; V section bss deklariramo spremenljivke, katerim dodamo vrednosti kasneje.
prvoStevilo resd 1 ; Resd je za stevilo, 1 bajt je za stevilo.
section .data ; Section data vsebuje spremenljivke, ki na nek na?in ze vsebujejo vrednosti.
vrednostSt db "%d", ; Z 0 zaklju?ek izpisa ali vnosa. vrednostPrvega ne moremo uporabljat kot izpis,
vnosStevilo db "Vnesi stevilo: ", 0 ; ker vanj shranimo vneseno stevilo.
izpisovanje db "Loop: %d", 10, 0 ; 10 je nova vrstica, 0 je konec izpisa.
main:
pushad ; Shranimo trenutno stanje uporabljenih registrov, splošnonamenske registre.
push dword vnosStevilo ; Na sklad porinemo vnosStevila, v tem primeru string.
call printf ; Poklicemo printf, ki izpise tisto, kar je v skladu.
add esp, 4 ; Po?istimo sklad. 4 Bajte.
push dword prvoStevilo ; Na sklad porinemo prvoStevilo, v tem primeru integer.
push dword vrednostSt ; Na sklad porinemo vrednostSt, v tem primeru string.
call scanf ; To stevilo preberemo in v %d se shrani vrednost prvoStevilo.
add esp, 8 ; Po?istimo sklad. 4 Bajte * 2.
mov ebx, 1 ; V register shranimo vrednost 1, ker povecujemo iz 1.
.loop1: ; Loop po primeru iz predavanj.
push ebx ; Na sklad porinemo ebx, ki vsebuje vrednost 1+loop.
mov eax, ebx ; Divide ecx vedno deli z vrednostjo eax. Moramo dati vrednost noter.
mov ecx, 11 ; V ecx vrzemo vrednost 11.
div ecx ; V edx se shrani ostanek.
cmp edx, 0 ; Primerja torej ostanek ga z 0.
jnz .loop2 ; ?e ni enako 0, presko?imo izpis in gremo dalje v "for" loop.
push dword izpisovanje ; Na sklad porinemo izpisovanje, ki vsebuje vrednost ebx.
call printf ; Poklicemo printf, ki izpise tisto, kar je v skladu.
add esp, 4 ; Po?istimo sklad. 4 bajte * 2 bajta. Spu?emo še tisto iz loop1.
.loop2:
add ebx, 1 ; Povecamo stevec za 1.
cmp ebx, [prvoStevilo] ; Primerjamo trenutni stevec v loopu z vnesenim stevilom.
mov edx, 0
jle .loop1 ; Jump less or equal. ?e je enako, se kon?a, druga?e gre nazaj noter.
popad ; Restoramo registre. Po?isti.
mov eax, 1 ; Exit komanda.
int 0x80 ; Invoka system call. V kombinaciji mov eax, 1 kli?e "exit()" in kon?a program.