在汇编中获得偶数输出时遇到一些问题

Having some problem with getting even number output in assembly

我在数组中进行了输入。然后我尝试打印数组中的偶数。我得到了预期的输出,但在打印结果后我得到了额外的数字。假设我的数组是 1,2,3 输出是

200000000000...

并继续。

我的代码:

include emu8086.inc

org 100h

define_scan_num
define_print_num
define_print_num_uns
.model small
.stack 100h
.data
a dw ?
b dw 50 dup(?)    
z dw ?

.code
main proc

mov ax, @data
mov ds,ax

call scan_num
printn ""

mov a,cx
mov bx,1

for1:
push cx
call scan_num
printn ""
mov b[bx],cx
add bx,2 
pop cx
loop for1

mov bx,1
mov cx,a  

for2:  
mov ax, b[bx]
mov dx,0
mov z,2
div z 
cmp dx,0  
je even
jne odd
loop for2

jmp skip

even:
mov ax,b[bx]
call print_num 
printn ""
add bx,2 
jmp for2

odd: 
add bx,2
jmp for2 

skip:
ret

main endp
end main
for2:  
mov ax, b[bx]
mov dx,0
mov z,2
div z 
cmp dx,0  
je even
jne odd
loop for2
jmp skip

以上代码是一个循环,应该 运行 次数有限。
它不会,因为外部放置的 evenodd case 在它们应该跳回到 loop for2 正确循环执行的指令。

一些原因和一个例子

  • 为什么要除以2看是不是偶数? test 最低位就够了。如果该位为 0 (jz) 则该数为偶数,如果该位为 1 (jnz) 则该数为奇数。
  • 为什么要将 evenodd case 放在循环外部?如果将它们保留在循环中会容易得多。少跳来跳去。
  • 为什么要复制 add bx, 2 这样的代码?看到这主要是结构不良代码的迹象。
  • 为什么要从奇数偏移量 1 开始寻址 words 数组?如果您决定将其更改为更合理的 0,那么在任何地方都这样做(在 for1for2 中)!

一个例子:

    xor     bx, bx       ; BX=0
    mov     cx, a
for2:  
    mov     ax, b[bx]
    test    ax, 1        ; TEST does not change the value in AX ...
    jnz     odd          ; print_num can use it without reloading!
even:
    call    print_num 
    printn ""
odd:
    add     bx, 2
    dec     cx
    jnz     for2
    ret
main endp
end main

为了获得更好的性能,您可以将 loop ... 替换为 dec cx jnz ...