Loops 汇编8086循环问题
伪代码如下所示:Loops 汇编8086循环问题,loops,assembly,x86-16,Loops,Assembly,X86 16,伪代码如下所示: read c //a double digit number for(i=1,n,i++) { if (n%i==0) print i;} 在汇编中,我将其写成: 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
read c //a double digit number
for(i=1,n,i++)
{ if (n%i==0)
print i;}
在汇编中,我将其写成:
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
我通过追踪其步骤进行了检查。第一次迭代进行得很顺利,然后在第二次迭代时,它使ax=初始值,cx=2,但在“div cx”时,它跳到我不知道的地方,并且不会在任何地方停止。它是:
push ax
mov al,12
nop
push 9
.
.
知道为什么吗?试着在div指令之前执行mov-dx,0。 基本上,每次跳转之后,dx寄存器中可能会有一些数据,所以可以在dx或XOR dx,dx中移动零。 这是必须做到的,因为否则分工的考虑将有所不同。 见此: 无符号除法 算法:
when operand is a byte:
AL = AX / operand
AH = remainder (modulus)
when operand is a word:
AX = (DX AX) / operand
DX = remainder (modulus)
例如:
MOV AX,203;AX=00CBh
MOV BL,4
BL分区;AL=50(32小时),AH=3
RET
cmp-ah,0;检查余数是否为0
这也是错误的,请检查。(我不是说“cmp xx,0”是非最佳的,而是说这里完全错了。你可能还想读一下)另外,如果CX是你的循环计数器,你不能在循环中使用cl,ch,CX,在不保存并稍后恢复其值的情况下,在div-cx中,实际上是将dx:ax的内容除以cx,但寄存器dx未初始化。在div cx之前使用cwd。@Tommylee2k:您可以使用循环计数器作为这样的试用除法循环中的除数;它确实撤消了它的修改。虽然首先只在DL中修改副本显然更简单。(使用字大小的除法也很奇怪,但打印方式只适用于一位数。)@vitsoft:你需要xor dx,dx
在div
之前,只cwd
在idiv
之前。不幸的是,我根据注释选择了错误的副本,代码使用了div
。但我不想再通过编辑来重复这篇文章,所以我想知道为什么我要花时间修改评论中的内容。:/哦,等等,是的,我确实这么做了,我甚至把我的头像设置为:P(cwd
可以作为无符号除法的大小优化,如果你知道AX将被签名为正数,但对于学习来说,这不是规范的始终有效的方式。)这看起来更像是一个注释。请参考以下内容扩展您的答案: