0

我刚开始学习assembly,我写了一些行来练习,但是我卡在需要显示结果的部分。

说明:我有一个min值和一个max值。我将这些值与 a 进行比较array,试图仅显示不在 inteval ( [min,max])中的值

这是我尝试过的(我知道我在这方面很糟糕,对不起!):

include emu8086.inc

ORG 100h   

mov cx, 5    

verificareMinim:   
           MOV AX,date                                                                                  
           MOV BX,minInterval                                                                                 
           CMP AX,BX 
           JB belowMinResults   

 loop verificareMinim      ; sfarsit pasul 1 



 verificareMaxim:  
            MOV AX,date 
            MOV BX,maxInterval
            CMP AX,BX
            JA  overMaxResults

  loop verificareMaxim  ; sfarsit pasul 2


 belowMinResults:
            int 21h
            JMP verificareMinim

 overMaxResults:  
            int 21h
            JMP verificareMaxim



maxInterval DW 10
minInterval DW 1
date DW -1,-4,11,3,7

RET ; return to operating system.
END ; directive to stop the compiler.

所以,我的问题是:

1)我的代码有什么问题?(问题如上所述,在Description

2)如何显示结果?

4

1 回答 1

2

如果您只想打印适合范围的数组的数字,则无需使用 2 个循环使其过于复杂。一个循环就足够了。

另一个问题是您没有为int 21hDOS 调用设置任何有意义的参数。

第三个问题是你没有更新你的指针。

第四个问题是您cx在第一个 ( verificareMinim) 循环之后不再设置。

第五个问题是您使用无符号条件跳转jbja有符号数。

第六个问题是您的代码进入无限循环,因为 whenloop verificareMaxim不再分支到verificareMaxim,执行继续belowMinResults,然后(如果int 21h没有崩溃,即),JMP verificareMinim使其成为无限循环。

第七个问题是ret指令在您的数据之后,并且永远不会到达。

你可以这样做:

    mov si,date ; si points to the array.
                ; some assemblers want mov si,offset array.
                ; lea si,date may also be used.

    mov cx,5    ; length of array date

编辑:打印不在区间内的数字。固定的。

编辑:修复了十六进制打印中的错误。

@verify_loop:
    mov ax,[si]           ; read value from array into ax
    cmp ax,[minInterval]  ; compare value of ax with the value of min_Interval
                          ; some assemblers want cmp ax,min_Interval
    jl  @number_is_ok     ; jump if less, signed conditional jump.

    cmp ax,[maxInterval]  ; compare value of ax with the value of max_Interval
                          ; some assemblers want cmp ax,max_Interval
    jle @number_not_valid ; jump if less or equal, signed conditional jump.

@number_is_ok:

    ; the number in ax is valid, print it here.

    ; I'll do the printing here the easy way: printing in
    ; hexadecimal, printing in other formats (say, decimal) left as an exercise.
    ; hint: use div and print always the remainder after converting it to ASCII
    ; 0...9.
    ;
    ; I'll just use int 21h/ah=02h here, dl contains the character to write.

    push cx

    mov cl,12d ; number of bits to shift.
               ; start with 12 (it's 16 minus 4).

    @print_loop:
        mov dx,ax

        shr dx,cl   ; shift dx cl bits to the right
        and dl,0x0F ; leave only the lower nibble (4 bits)
        cmp dl,9
        jbe @between_0_and_9 ; jump if between or equal to 9
                             ; (unsigned conditional jump)

            add dl,('a'-'9'-1) ; Edit: fixed bug here.
                               ; Lowercase hexadecimal letters a-f
                               ; (change to 'A' for uppercase)
    @between_0_and_9:
        add dl,'0'           ; convert to printable ASCII '0'...'9', 'a' ... 'f'

        push ax    ; according to Ralph Brown's interrupt list,
                   ; int 21h/ah=02 modifies al.
        mov ah,2   ; print character to screen
        int 21h    ; character in dl
        pop ax

        sub cl,4        ; next time shift 4 bits less
        jnc @print_loop ; continue if there's still bits left

    pop cx

@number_not_valid:
    add si,2            ; next word in array date.
    dec cx              ; decrement counter.
    jnz @verify_loop    ; continue if there's still words in array date.

; now everything is done.

    mov ax,4C00h
    int 21h      ; int 21h/ah=4Ch, return to DOS, return code in al.
                 ; int 20h works too, no return code.
                 ; ret works too, but only in .COM files.

maxInterval DW 10
minInterval DW 1
date        DW -1, -4, 11, 3, 7
于 2013-03-02T18:20:09.703 回答