If I understand what you are trying to do, I think you have a misunderstanding of how cmp
and jz
work.
cmp
works by subtracting the source (second) operand from the destination (first) without storing the result, and setting flags based on the result. For unsigned numbers, the relevant flags are carry and zero. If the source was bigger than the destination, then the subtraction will borrow from its highest position, which has the result of setting the carry flag. If the source and destination are the same, then the result will be zero, and the zero flag will be set. If the source is smaller than the destination, then the subtraction won't result in 0 or cause a carry, so both flags will be 0.
The jz
(and other conditional jumps) perform a jump depending on the current state of the flags. Specifically, jz
will perform the jump if the zero flag is set. Since cmp
sets the zero flag to indicate that its operands were equal, the jump if equal (je
) instruction is actually the same as the jump is zero instruction. The jump if carry (jc
) and jump if below (jb
) instructions are also the same, for the same reason.
Since cmp
sets the flags to indicate which operand was bigger, the jz
instruction can be confusing. It will jump if the operands were equal, not if one of them was zero. Looking at your code from step1
:
div edi
cmp edx, 1
jz step2
I think what you are trying to do is jump to step2
if the remainder of the division is 0, but due to the way cmp
works, you will actually jump to step2 if the remainder is 1. The fix is simple: change the 1 to 0. (Note: I changed jz
to je
because it better explains the reason for the jump. As I stated earlier, they are exactly the same.)
div edi
cmp edx, 0
je step2
Additionally, you don't preserve the old value in the case where you don't find a factor. For example, if the input value was 3, your step1
loop would work like this:
- Start:
eax
=3, edi
=2
- Divide
eax
by edi
. Store the quotient in eax
and the remainder in edx
.
- Now,
eax
=3/2=1, and edx
=3%2=1
- Is
edx
0? If so, print edi
and go to the beginning of the loop.
- Add 1 to
edi
. It is now 3.
- Perform step 2 with the new values,
eax
=1 and edi
=3.
- Now,
eax
=1/3=0, edx
=1%3=1
- ...
Notice that, even though you didn't find a factor, the value of eax
has changed. What you need to do is save its value before you do the division. You can use your hold
variable for this, which will mean it is already updated whenever you find a factor. All you have to do is store the value before starting your loop, and restore it at the beginning of each loop.
mov hold, eax
step1: mov eax, hold
xor edx, edx
...