1

The pseudocode is the following:

read c        //a double digit number
for(i=1,n,i++)
{ if (n%i==0)
     print i;}

In assembly I have written it as:

mov bx,ax   ;  ax was the number  ex.0020, storing a copy in bx.

mov cx,1    ; the start of the for loop
.forloop:
mov ax,bx   ; resetting ax to be the number(needed for the next iterations)
div cx
cmp ah,0    ; checking if the remainder is 0 
jne .ifinstr
add cl 48    ;adding so my number would be displayed later as decimal
mov dl,cl   ;printing the remainder
mov ah,2
int 21h
sub cl,48   ;converting it back to hexa
.ifinstr:
inc cx      ;the loop goes on
cmp cx,bx
jle .forloop

I've checked by tracing its steps. The first iteration goes well, then, at the second one, it makes ax=the initial number and cx=2 as it should, but at 'div cx' it jumps somwhere unknown to me and it doesn't stop anywhere. It does:

push ax
mov al,12
nop
push 9
.
.

Any idea why it does that?

  • `cmp ah,0 ; checking if the remainder is 0 ` this is also wrong, check [`DIV` instruction description](http://x86.renejeschke.de/html/file_module_x86_id_72.html). (and I'm not talking about "cmp xx,0" being non-optimal, but about being completely wrong here. Still you may want to read also http://stackoverflow.com/a/41175294/4271923 ) – Ped7g Mar 10 '17 at 14:22
  • also if CX is your loop counter, you cannot use cl, ch, cx inside your loop, without saving and later restoring it's value – Tommylee2k Mar 10 '17 at 14:44
  • 2
    Also in your **div cx** you're actually dividing the contents of dx:ax by cx but register dx was not initialized. Use **cwd** before **div cx**. – vitsoft Mar 11 '17 at 11:04
  • @Tommylee2k: you can use the loop counter *as* the divisor in a trial-division loop like this; it does undo its modification. Although it would obviously be simpler to only modify the copy in DL in the first place. (It's also weird to use word-sized division but to print in a way that only works for single-digit numbers, though.) – Peter Cordes Jun 11 '21 at 07:55
  • 1
    @vitsoft: You want `xor dx,dx` before `div`, only `cwd` before `idiv`. Unfortunately I picked the wrong duplicate based on comments, the code uses `div`. But I'd rather not bump this yet another duplicate by editing, so IDK why I'm spending time correcting stuff in comments. :/ Oh wait, yes I do, I even set my avatar to that :P (`cwd` is usable as a size optimization for unsigned division if you know AX will be signed positive, but for learning it's not the canonical always-works way.) – Peter Cordes Jun 11 '21 at 07:57

1 Answers1

1

try to do mov dx,0 just before div instruction. Basically every time you come after jump, there may be some data in dx register, so you can just move zero in dx or XOR dx,dx. This is to be done, because otherwise division will be considered differently. See this: Unsigned divide.

Algorithm:

when operand is a byte:
AL = AX / operand
AH = remainder (modulus) 

when operand is a word:
AX = (DX AX) / operand
DX = remainder (modulus) 

Example:

MOV AX, 203 ; AX = 00CBh MOV BL, 4 DIV BL ; AL = 50 (32h), AH = 3 RET

Lohitaksh Trehan
  • 304
  • 2
  • 12
  • This looks more like a comment. Please extend your Answer by referring to [How do I write a good answer](https://stackoverflow.com/help/how-to-answer) – Teocci Apr 22 '17 at 07:49