DOS segment
.model small
.stack 100h
.data
array1 dw 1,4,6,3,7 ; since division 8 bit divisor require 16 bit dividend
.code
main proc
mov ax,@data
mov ds,ax
lea si,array1
mov cx,5
l1:
mov ax,[si]
mov bl,2
div bl
cmp ah,0
jne odd **if the remainder is not 0 means even**
resume:
inc si
loop l1
odd:
push ax **I am using stack**
jmp resume
mov cx,5
l2:
mov ax,[si]
mov bl,2
div bl
cmp ah,0
je even **if the remainder is 0 means even**
re:
inc si
loop l2
even:
push ax
jmp re
mov cx,5
l3:
pop dx
mov ah,2
int 21h
loop l3
main endp
end main
我相信我的算法是正确的,但是我面临的问题是除法错误。我环顾四周,它发生在CX=0
时,但是循环如何工作?我很困惑。
我会很高兴有人告诉我解决方案
答案 0 :(得分:0)
...如果余数不为0则表示偶数
...如果余数为0则表示偶数
不可能两个都同时正确!
lea si,array1 mov cx,5 l1: mov ax,[si] mov bl,2 div bl cmp ah,0 jne odd **if the remainder is not 0 means even** resume: inc si loop l1 odd: push ax **I am using stack** jmp resume
问题是您将 odd 标签放在完成循环的LOOP
指令的下面(当CX
变为0时)。这些push ax
和jmp resume
指令将错误地插入代码!
您需要通过绕过push ax
来重新组织代码:
cmp ah, 0
je Even
push ax ; This pushes an ODD number BUT DOES IT ? (1)
Even:
inc si ; This advances to the next number BUT DOES IT ? (2)
loop l1
(1)AX
寄存器不再保存数组中的数字,因此您需要使用push word ptr [si]
从数组中推送单词。
(2)由于数组包含单词,因此您需要使用add si, 2
前进2。
mov cx,5 l2: mov ax,[si] mov bl,2 div bl cmp ah,0 je even **if the remainder is 0 means even** re: inc si loop l2 even: push ax jmp re
我在第一个循环中说的所有内容在这里也适用。另外,您需要使用SI
初始化lea si, array1
寄存器。
mov cx,5
l3:
pop dx
mov ah,2
int 21h
loop l3
从堆栈中弹出的是一个数字,但是DOS.Printchar函数在DL
中需要一个字符。需要一点转换:
pop dx
add dl, '0'
程序中的某些问题源于您使用2除以测试偶数/奇数的事实。这使您将数组定义为单词,而忘记更改inc si
指令。
查看数字是偶数还是奇数的方法是查看其最低位。您可以使用test
指令:
array1 DB 1, 4, 6, 3, 7
...
L1:
mov al, [si]
test al, 1
jz Even
push ax ; Pushing the odd number still in the AL register
Even:
inc si
dec cx
jnz L1