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

时间:2019-04-30 22:07:51

标签: loops assembly x86-16 emu8086

我接受了数组中的输入。然后,我尝试在数组中打印偶数。我得到了预期的输出,但是在打印结果后得到了额外的数字。就像假设我的数组是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

1 个答案:

答案 0 :(得分:1)

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 odd 案例应该跳回到loop for2指令以获取它们时,它们会跳回到循环的顶部。正确执行循环。

为什么和一个例子

  • 为什么要除以2以查看数字是否为偶数? test最低位就足够了。如果该位为0(jz),则该数字为偶数;如果该位为1(jnz),则该数字为奇数。
  • 为什么将 even odd 案例放在循环外部?如果将它们保留在循环中会容易得多。少跳来跳去。
  • 您为什么要复制类似add bx, 2的代码?看到这主要是表示结构不良的代码。
  • 为什么要从奇数偏移量1开始寻址单词的数组?如果您决定将其更改为更合理的0,则可以在任何地方(在 for1 for2 中)进行操作!

一个例子:

    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 ...