Dannon Gilbert
Dannon Gilbert

Reputation: 71

Looks like I go an infinite loop going in MASM x86! I think I need some help understanding what exactly is going on

So, I have my code, and while I want some assistance with it, what I really want is help understanding what it is doing instead of what I want it to do. Can anyone give me the rundown of reading the code's language?

fibSeq:
mov     ecx, userNum            ;takes user number for loop count
mov     eax, 0                  ;x = 0
mov     ebx, 1                  ;y = 1

fibSeq2:
mov     edx, eax 
add     edx, ebx                ;sum = x + y
mov     eax, ebx                ;x = y
mov     ebx, edx                ;x = sum
mov     edx, ebx
call    writeint                ;prints the value of fib seq
mov     edx, OFFSET spaces      ;adds five spaces inbetween each number
call    writestring             
mov     eax, count              ;moves count into eax register
add     eax, 1                  ;adds 1 to count
jmp     divbyFive               ;jump to check if count is divisible by 5

JMP     done                    ;once ecx is 0, jmp should go to done

divbyFive:                      ;check if count is divisible by 5
mov     edx, 0                  ;clearing the edx register
mov     eax, count              ;moving count into eax
mov     ecx, 5                  ;count / 5
div ecx
cmp     edx, 0                  ;if the remainder = 0, jump to new line
JE      newLine
JNE     fibSeq2                 ;otherwise go back to the sequence

newLine:
call crlf                       ;if the count is divisible by 5 with no remainder, prints a new line
jmp fibSeq2                     ;afterwards, jumps back up to fibSeq2

loop    fibSeq2     

done:

Right now it is just printing +1 over and over again but what I want it to do is print the numbers in the Fibonacci sequence, until ecx is 0, and start a new line every 5 digits.

Example:

0 1 1 2 3

5 8 13 21 34

and so on!

Upvotes: 1

Views: 358

Answers (1)

prl
prl

Reputation: 12435

There are several problems with this code.

  1. It uses the same registers for multiple purposes. eax is used to hold x, but also to increment count and to do the div. ecx is used for the loop counter, but also in the div.

  2. After incrementing count, the new value is not stored back into the variable, so it is lost.

  3. There are several unreachable instructions, because they follow an unconditional jump and don’t have a label.

The loop instruction isn’t terribly useful; you can do the same thing with dec followed by jnz, using any register or memory location, instead of being constrained to use ecx.

There are three unused registers, edi, esi, and ebp, which can be used for x, y, and the loop counter. You can then use eax, edx, and ecx as temporaries, to compute sum, increment count, and divide.

You should save these registers before using them. (You should also save ebx, by the way.) An advantage of any of these is that they will be preserved by any functions you call (e.g., writestring), when following most 32-bit calling conventions. (But Irvine32 functions typically preserve all registers other than their return value, using their own special calling convention.)

Upvotes: 3

Related Questions