Возникли проблемы с получением четного числа в сборке - PullRequest
2 голосов
/ 01 мая 2019

Я взял ввод в массив.Затем я попытался напечатать четные числа в массиве.Я получил вывод, как и ожидалось, но я получаю дополнительные цифры после печати результата.Например, предположим, что мой массив равен 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 Ответ

1 голос
/ 01 мая 2019
for2:  
mov ax, b[bx]
mov dx,0
mov z,2
div z 
cmp dx,0  
je even
jne odd
loop for2
jmp skip

Приведенный выше код является циклом, который должен выполняться ограниченное количество раз.
Это не так, потому что даже и * размещены снаружи1007 * нечетных случаев возвращаются к началу цикла, когда они должны вернуться к инструкции loop for2 для правильного выполнения цикла.

Некоторые причины и пример

  • Почему вы делите на 2, чтобы увидеть, является ли число четным?Этого достаточно для test младшего бита.Если этот бит равен 0 (jz), то число четное, если этот бит равен 1 (jnz), то число нечетное.
  • Почему вы ставите четное и нечетные случаи вне цикла?Намного проще, если вы держите их в цикле.Меньше прыгать.
  • Почему вы дублируете код вроде 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 ....

...