0

学び始めたばかりassemblyで、練習用の行をいくつか書きましたが、結果を表示する必要がある部分で立ち往生しています。

説明:私にはmin価値と価値がありmaxます。これらの値をと比較して、間隔( )arrayにない値のみを表示しようとしています。[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つのループを使用して複雑にしすぎる必要はありません。1つのループで十分です。

int 21hもう1つの問題は、 DOS呼び出しに意味のあるパラメーターを設定していないことです。

3番目の問題は、ポインターを更新しないことです。

cx4番目の問題は、最初の(verificareMinim)ループの後で再度設定しないことです。

5番目の問題は、符号なし条件付きジャンプjbと符号付きja数値を使用することです。

6番目の問題は、コードが無限ループに陥ることです。これは、にloop verificareMaxim分岐しなくなるとverificareMaxim、実行が続行されbelowMinResults、(int 21hクラッシュしない場合は)JMP verificareMinim無限ループになります。

7番目の問題は、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

編集:間隔内にない数値を出力します。修理済み。

編集: 16進印刷のバグを修正しました。

@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 に答える