2

このコードは、オンラインの例から取られています。DL に出力したい変数があるとします。

DISPLAY_HEX PROC NEAR
    MOV BL,DL   

    MOV BH,0    
    MOV CL,4    

    SHL BX,CL   
    MOV DL,BH   

    CALL ONE_DIGIT  

    MOV CL,4    
    SHR BL,CL   
    MOV DL,BL   

    CALL ONE_DIGIT  

    RET     
DISPLAY_HEX ENDP


ONE_DIGIT PROC NEAR

    CMP DL,9    
    JA LETTER   

    ADD DL,48
    JMP NEXT    

LETTER: ADD DL, 'A'-10  

NEXT:   MOV AH,02H  
    INT 21H 

END:    RET     
ONE_DIGIT ENDP

なぜシフト?小数のように印刷できませんか?また、ここでSHRSHLの両方が使用されているのはなぜですか?

4

2 に答える 2

1

あなたのコードは非常に複雑すぎて、混乱したのも不思議ではありません。BX を左シフトすることで DL の上位ニブルを取得しているため、2 つのニブルは BH と BL に分割されますが、BL のニブルは上位 4 バイトにあります。

上位 4 ビットをレジスターの最下位に移動するには、1 つのシフトが必要です。

AND を使用して下位 4 ビットのみを保持する方が簡単で、実際の 8086 でははるかに高速です (1 クロック サイクルで任意のシフトを実行できるバレル シフター ALU を備えた最新の CPU とは異なり、シフトの各カウントにクロック サイクルが必要でした)。 .

これはよりシンプルで理解しやすい実装であり、よりコンパクトであるため、実際の 8086 よりも高速で優れています。

; Input in DL
; clobbers AX, CL, DX
DISPLAY_HEX PROC NEAR
    mov  dh, dl          ; save a copy for later

    mov  cl, 4
    shr  dl, cl          ; extract the high nibble into an 8-bit integer

    CALL ONE_DIGIT  

    and  dh, 0Fh         ; clear the high nibble, keeping only the low nibble
    mov  dl, dh          ; and pass it to our function
    CALL ONE_DIGIT  

    RET     

DISPLAY_HEX ENDP

コードサイズを節約するために、 mov dl, 0Fh/and dl, dhは命令ごとに 3 バイトではなく 2 バイトにand dh, 0Fhなりmov、アウトオブオーダー実行のクリティカル パスから外れます。

の実装にONE_DIGITは、不必要に複雑な分岐もあります。(多くの場合、ルックアップ テーブルを使用してニブル -> ASCII を実装しますが、必要なブランチは 2 つではなく 1 つだけです。extra を実行すると、extraaddよりも安価ですjmp。)

; input: DL = 0..15 integer
; output: AL = ASCII hex char written
; clobbers = AH    
ONE_DIGIT PROC NEAR
    CMP   DL,9    
    JBE   DIGIT   

    ADD   DL, 'A'-10  - '0'
DIGIT:
    ADD   DL, '0'

    MOV AH,02H  
    INT 21H      ; write char to stdout, return in AL.  Checks for ^c/break
    RET
ONE_DIGIT ENDP

(DH と DL でそれぞれを分離した後) 両方のニブルを一度に操作するようにADD dx, '00'(および を変更して)実行することもできます。cmp

/は AH を変更しないMOV AH,02Hため、をホイストすることもできます。.int 21hah=2

ただし、パフォーマンスを気にする場合は、2 文字の文字列を作成し、1 つのint 21hシステム コールを使用して両方の数字を一度に出力します。

于 2018-06-05T03:24:21.373 に答える