0

It gets stuck in an infinite loop in function "prebroj". It should count how many digits there are in my result number so i can return it as a string later and exit when %eax becomes 0. When I run it in the debugger when i divide my number (%eax) by the required base (%ecx) so as to get how many digits there is, at one point after the division it returns a very strange number to %eax, but the remainder of the division in %edx keeps returning perfectly normal, even though the resulting number in %eax makes no sense whatsoever. Here is the code, it's rather long but I figured it might be helpful to provide the whole thing. The problem loop is at line 152, near the end. I put a bunch of comments next to it so it's easier to find (the only problem is the loop, I just put the whole program in case it might be relevant, short program description in top comments):

#unsigned saberi2 (char *num1, unsigned base1, char *num2, unsigned, base2, char *sum, unsigned *sum_length, unsigned sum_base);
#           8       12      16      20  24      28      32
#the subprogram is called from a c program and takes the first 2 numbers from args 1 and 3 as strings (to be converted), their respective bases from args 2 and 4, and returns the sum as a string at the address from arg 5
.text
.globl saberi2

saberi2:
pushl %ebp
movl %esp, %ebp
pushl %ebx
pushl %esi
subl $16, %esp          # -4(%ebp) i -8(%ebp) su prvi i drugi broj
movl $1, -8(%ebp)
movl $0, -12(%ebp)

prov_prvi:
movl 8(%ebp), %esi
movb (%esi), %bl
cmpb $'-', %bl
jne nm1
movl $-1, -8(%ebp)
incl %esi
jmp np1
nm1:
cmpb $'+', %bl
jne np1
incl %esi
np1:
movl $0, %eax
movl 12(%ebp), %ecx
cmpl $10, %ecx
ja preko10_1

ispod10_1:
movb (%esi), %bl
cmpb $0, %bl
je kraj1
subb $'0', %bl
cmpb $0, %bl
jl greska1
cmpb 12(%ebp), %bl
jg greska1
mull %ecx
movb %bl, -12(%ebp)
addl -12(%ebp), %eax
incl %esi
jmp ispod10_1

preko10_1:
movb (%esi), %bl
cmpb $0, %bl
je kraj1
subb $'0', %bl
cmpb $0, %bl
jl greska1
cmpb $9, %bl
jg slovo1
mull %ecx
movb %bl, -12(%ebp)
addl -12(%ebp), %eax
incl %esi
jmp preko10_1
slovo1:
subb $7, %bl            #17 je razmak od 0 do A
cmpb $10, %bl
jl greska1
cmpb 12(%ebp), %bl
jg greska1
mull %ecx
movb %bl, -12(%ebp)
addl -12(%ebp), %eax
incl %esi
jmp preko10_1

kraj1:
movl -8(%ebp), %ecx
mull %ecx
movl %eax, -4(%ebp)

prov_drugi:
movl 16(%ebp), %esi
movb (%esi), %bl
movl $1, -8(%ebp)
cmpb $'-', %bl
jne nm2
movl $-1, -8(%ebp)
incl %esi
jmp np2
nm2:
cmpb $'+', %bl
jne np2
incl %esi
np2:
movl $0, %eax
movl 20(%ebp), %ecx
cmpl $10, %ecx
ja preko10_2

ispod10_2:
movb (%esi), %bl
cmpb $0, %bl
je kraj2
subb $'0', %bl
cmpb $0, %bl
jb greska2
cmpb 20(%ebp), %bl
ja greska2
mull %ecx
movb %bl, -12(%ebp)
addl -12(%ebp), %eax
incl %esi
jmp ispod10_2

preko10_2:
movb (%esi), %bl
cmpb $0, %bl
je kraj2
subb $'0', %bl
cmpb $0, %bl
jl greska2
cmpb $9, %bl
jg slovo2
mull %ecx
movb %bl, -12(%ebp)
addl -12(%ebp), %eax
incl %esi
jmp preko10_2
slovo2:
subb $7, %bl            #17 je razmak od 0 do A
cmpb $10, %bl
jl greska2
cmpb 20(%ebp), %bl
jg greska2
mull %ecx
movb %bl, -12(%ebp)
addl -12(%ebp), %eax
incl %esi
jmp preko10_2

kraj2:
movl -8(%ebp), %ecx
mull %ecx
addl -4(%ebp), %eax
jo greska3

ispis:
movl 24(%ebp), %ebx     #ebx je adresa zbira
movl %eax, -4(%ebp)     #eax je zbir
movl $0, %esi           #esi je broj cifara zbira
movl 32(%ebp), %ecx     #ecx je baza zbira

prebroj:
cmpl $0, %eax           #brojanje cifara zbira
je unesi            #-----------------------------------------------
divl %ecx           #THIS IS THE LOOP-------------------------------
incl %esi           #-----------------------------------------------
movl %eax, -12(%ebp)
jmp prebroj

unesi:                  #unos cifara na adresu iz arg
movl %esi, 28(%ebp)
movl -4(%ebp), %eax
cmpl $0, %eax
jg nmi
movb $'-', (%ebx)
incl %esi
nmi:
movb $0, (%ebx, %esi, 1)
decl %esi
cmpl $10, %ecx
ja preko10_i

ispod10_i:
cmpl $0, %eax
je preende
divl %ecx
addb $'0', %dl
movb %dl, (%ebx, %esi, 1)
decl %esi
jmp ispod10_i

preko10_i:
cmpl $0, %eax
je preende
divl %ecx
cmpb $9, %dl
ja slovoi
addb $'0', %dl
movb %dl, (%ebx, %esi, 1)
decl %esi
jmp preko10_i
slovoi:
addb $55, %dl
movb %dl, (%ebx, %esi, 1)
decl %esi
jmp preko10_i

greska1:
movl $1, %eax
jmp ende

greska2:
movl $2, %eax
jmp ende

greska3:
movl $3, %eax
jmp ende

preende:
movl $0, %eax
ende:
popl %esi
popl %ebx
movl %ebp, %esp
popl %ebp
ret
Jester
  • 56,577
  • 4
  • 81
  • 125
Fish
  • 91
  • 7
  • 2
    It's the usual issue of not zeroing `edx`. Read the reference manual about how `div` works. You will see it uses `edx` as the top 32 bits of the dividend. If you only have 32 bits, you need to zero it. – Jester May 25 '17 at 19:16
  • It worked, cheers! – Fish May 25 '17 at 19:33
  • Possible duplicate of [Wrong answer from DIV assembly](https://stackoverflow.com/questions/30927331/wrong-answer-from-div-assembly) – Johan May 26 '17 at 13:09
  • Never use div!, always use idiv with explicit operands. Problem solved. – Johan May 26 '17 at 13:10
  • Possible duplicate of [Integer Overflow problem](https://stackoverflow.com/questions/5606895/integer-overflow-problem), https://stackoverflow.com/questions/2255960/masm-division-overflow, https://stackoverflow.com/questions/36464879/when-and-why-do-we-sign-extend-and-use-cdq-with-mul-div, https://stackoverflow.com/questions/38416593/why-should-edx-be-0-before-i-use-div-opcode?noredirect=1 etc. etc. – Cody Gray - on strike May 26 '17 at 13:56

0 Answers0