程序集8086,计算数组

时间:2018-06-07 15:02:04

标签: arrays assembly x86-16 emu8086

所以我在装配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 :(得分:1)

mov ax, number
call print
jmp fin

暂不考虑计算偶数。首先,您需要正确显示数字 另外,由于jmp fin指令,无论如何都不会执行任何附加指令。

您的打印程序有几个问题:

  • 你用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

进一步阅读并更好地理解上述代码的工作原理 Displaying numbers with DOS