我想先打印偶数,然后再打印奇数

时间:2020-05-12 20:05:42

标签: assembly emu8086

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时,但是循环如何工作?我很困惑。

我会很高兴有人告诉我解决方案

1 个答案:

答案 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 axjmp 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