在汇编中获得偶数输出时遇到一些问题
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
以上代码是一个循环,应该 运行 次数有限。
它不会,因为外部放置的 even 和 odd case 在它们应该跳回到 loop for2
正确循环执行的指令。
一些原因和一个例子
- 为什么要除以2看是不是偶数?
test
最低位就够了。如果该位为 0 (jz
) 则该数为偶数,如果该位为 1 (jnz
) 则该数为奇数。
- 为什么要将 even 和 odd case 放在循环外部?如果将它们保留在循环中会容易得多。少跳来跳去。
- 为什么要复制
add bx, 2
这样的代码?看到这主要是结构不良代码的迹象。
- 为什么要从奇数偏移量 1 开始寻址 words 数组?如果您决定将其更改为更合理的 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 ...
。
我在数组中进行了输入。然后我尝试打印数组中的偶数。我得到了预期的输出,但在打印结果后我得到了额外的数字。假设我的数组是 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
以上代码是一个循环,应该 运行 次数有限。
它不会,因为外部放置的 even 和 odd case 在它们应该跳回到 loop for2
正确循环执行的指令。
一些原因和一个例子
- 为什么要除以2看是不是偶数?
test
最低位就够了。如果该位为 0 (jz
) 则该数为偶数,如果该位为 1 (jnz
) 则该数为奇数。 - 为什么要将 even 和 odd case 放在循环外部?如果将它们保留在循环中会容易得多。少跳来跳去。
- 为什么要复制
add bx, 2
这样的代码?看到这主要是结构不良代码的迹象。 - 为什么要从奇数偏移量 1 开始寻址 words 数组?如果您决定将其更改为更合理的 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 ...
。