сборка 8086, считать четные числа в массиве - PullRequest
0 голосов
/ 07 июня 2018

Таким образом, я наткнулся на один пример в своем блоке для сборки 8086, и я мог бы использовать некоторую помощь для завершения кода

Так что пример выглядит так: есть массив целых чисел, вычислить количество четных элементов вмассив

.model small
.stack
.data
arr dw 10 dup (1,2,3,4,5,6,7,8,9,10)
msg db 'number of even elements is:', '$'   ;;
.code
;printing
print proc a:word

        push bp
        mov bp, sp

        mov ax, a
        mov cx, 10
        mov bx, 0
        cmp ax, 0  

        jne begin
        mov dl, 0
        add dl, '0'
        mov ah, 2
        int 21h
        jmp toend

    begin: 
        cmp ax, 0
        je print

        mov dx, 0
        div cx

        push dx
        inc bx
        jmp begin

    print:   

        cmp bx, 0
        je kraj

        pop dx
        add dl, '0'
        mov ah, 2
        int 21h

        dec bx
        jmp print

toend:
        mov dl, 10 
        mov ah, 2
        int 21h

        pop bp
        ret 2

print endp

main:

    mov ax, @data
    mov ds, ax

    mov ax, ;number
    call print
    jmp fin

Я посмотрел какой-то предыдущий код и как-то пытался заставить эту работу ..

Так что мой вопрос: я вообще на правильном пути, должен ли я использовать idivинструкция или?

РЕДАКТИРОВАТЬ: я не могу получить что-то еще, кроме "21243" в результате, и, кстати, я попытался вычислить некоторые другие вещи и потерял в процессе, вот полный код:

; there is an array of integers.  calculate the number of
; even elements in the array.

.model small
.stack
.data
arr dw 10 dup (1,2,3,4,5,6,7,8,9,10)
msg db 'Average (in procents): ', '$'
msg1 db 'Average of even elements: ', '$'
msg2 db 'Sum  is:', '$'  ;;
msg3 db 'Number of even elements is :', '$'   ;;
limit dw ? ; length * 2, because we save dw (length of 2 bytes)
number dw 2345     ;;
sum dw 0   ;;
.code
print proc a:word

        push bp
        mov bp, sp

        mov ax, a
        mov cx, 10
        mov bx, 0
        cmp ax, 0  

        jne begining
        mov dl, 0
        add dl, '0'
        mov ah, 2
        int 21h
        jmp toend

    begining:
        cmp ax, 0
        je print

        mov dx, 0
        div cx

        push dx
        inc bx
        jmp begining

    print:  

        cmp bx, 0
        je toend

        pop dx
        add dl, '0'
        mov ah, 2
        int 21h

        dec bx
        jmp print

toend:
        mov dl, 10
        mov ah, 2
        int 21h

        pop bp
        ret 2

print endp

main:

    mov ax, @data
    mov ds, ax

    mov ax, number
    call print
    jmp fin




    shl ax, 1           ;mul 2
    mov limit, ax

    mov bx, 0
    mov cx, 2

poc:

    cmp bx, limit
    je k

    mov ax, arr[bx]
    ;mov dx, 0 ;
    ;div cx    ;
    cwd

    idiv cx  ;signed division
    cmp dx, 0
    jne  jumpp

    mov ax, number
    inc ax
    mov number, ax

    mov ax, sum
    add ax, arr[bx]
    mov sum, ax

jumpp:

    add bx, 2 ;because 'length' of elements is 2 bytes
    jmp poc

k:

    mov ax, 100
    mov bx, number
    mul bx

    mov dx, 0     ; xor dx, dx
    mov bx, length arr  ; length of array = 10 so this is mov bx, 10
    div bx    

    mov es, ax
    mov dl, offset msg
    mov ah, 9
    int 21h

    mov ax, es
    push ax
    call print

    ; mov dl, offset msg2
    ; mov ah, 9
    ; int 21h

    mov ax, sum
    push ax
    call print

    ; mov dl, offset msg3
    ; mov ah, 9
    ; int 21h

    mov ax, number
    push ax
    call print

    ; mov dl, offset msg1
    ; mov ah, 9
    ; int 21h

    mov ax, sum
    mov dx, 0
    cwd
    mov bx, number
    cmp bx, 0
    je here
    idiv number

    push ax
    call print
    jmp fin

here:
    mov dl, 0
    add dl, '0'
    mov ah, 2
    int 21h

fin:
    mov ah, 4ch
    int 21h

end main

1 Ответ

0 голосов
/ 10 июня 2018
mov ax, number
call print
jmp fin

Пока не думайте о подсчете четных чисел.Во-первых, вам нужно правильно отобразить число.
Кроме того, из-за инструкции jmp fin ни одна из дополнительных инструкций не выполняется в любом случае.

Ваша print процедура имеет несколько проблем:

  • Вы заканчиваете его ret 2, что означает, что он должен вызываться с аргументом размером в слово, помещенным в стек, но его нет!

  • Вы передали аргумент через регистр AX, но почти сразу вы уничтожили его с помощью mov ax, a.

  • Ваша print процедура содержитэтикетка с тем же именем печать .Зная, что emu8086 является неработающим программным обеспечением, я не могу сказать, что инструкция call print достигает процедуры или метки.

Следующий код должен работать.Убедитесь, что это так, и опирайтесь на это.Добавьте к этому мелочи (всего несколько строк кода) и не продолжайте добавлять больше, пока он не заработает, как следует!

.model small
.stack
.data
    number dw 2345

.code

; IN (ax) OUT () MOD (ax,bx,cx,dx)
print:
    mov  cx, 10     ; Constant divider
    mov  bx, 0      ; Count pushes
  divide:
    mov  dx, 0      ; Dividing DX:AX
    div  cx
    push dx
    inc  bx
    cmp  ax, 0
    jne  divide
  show:
    pop  dx         ; Always at least 1 pop here
    add  dl, '0'
    mov  ah, 02h    ; DOS.DisplayCharacter
    int  21h
    dec  bx
    jnz  show
    mov  dl, 10     ; Linefeed, Don't you need carry return (13) too?
    mov  ah, 02h
    int  21h
    ret

main:
    mov ax, @data
    mov ds, ax

    mov ax, number
    call print
    jmp fin

    ...

fin:
    mov  ax, 4C00h  ; DOS.Terminate
    int  21h

end main

Для дальнейшего чтения и лучшего понимания, почему работает приведенный выше код, см. Отображение чисел с DOS

...