1

ループを使用して最初の 20 の数字を出力したかったのです。

16 進数と 10 進数のコードは同じであるため、最初の 9 つの数値を出力することはまったく問題ありませんが、10 番目の数値からは、各数値を適切なコードに変換し、それを変換して文字列に保存し、最終的に表示する必要がありました。

あれは、

If (NUMBER > 9)
ADD 6D
;10d = 0ah --(+6)--> 16d = 10h
IF NUMBER IS > 19
ADD 12D
;20d = 14h --(+12)--> 32d = 20h

次に、各数値を回転およびシフトして、目的の出力数値を取得します。つまり、

DAA          # let al = 74h = 0111.0100

XOR AH,AH    # ah = 0 (Just in case it wasn't)
             # ax = 0000.0000.0111.0100

ROR AX,4     # ax = 0100.0000.0000.0111 = 4007h
SHR AH,4     # ax = 0000.0100.0000.0111 = 0407h
ADD AX,3030h # ax = 0011.0100.0011.0111 = 3437h = ASCII "74" (Reversed due to little endian)

そして、結果を文字列に格納して表示します。つまり、

MOV BX,OFFSET Result    ;Let Result is an empty string
MOV byte ptr[BX],5      ;Size of the string
MOV byte ptr[BX+4],'$'  ;String terminator
MOV byte ptr[BX+3],AH   ;storing number
MOV byte ptr[BX+2],AL

MOV DX,BX
ADD DX,02  ;Displaying the result
MOV AH,09H ;Interrupt 21 service to display string
INT 21H

そして、これが適切なコメント付きの完全なコードです。

MOV CX,20  ;Number of iterations
MOV DX,0   ;First value of the sequence

L1:

    PUSH DX
    ADD DX,30H  ; 30H is equal to 0 in hexadecimal , 31H = 1 and so on
    MOV AH,02H  ; INTERRUPT Service to print the DX content
    INT 21H
    POP DX
    ADD DX,1
    CMP DX,09   ; if number is > 9 i.e 0A then go to L2
    JA L2
LOOP L1


L2:
    PUSH DX
    MOV AX,DX
    CMP AX,14H   ;If number is equal to 14H(20) then Jump to L3
    JE L3
    ADD AX,6D    ;If less than 20 then add 6D
    XOR AH,AH    ;Clear the content of AH

    ROR AX,4     ;Rotating and Shifting for to properly store
    SHR AH,4

    ADC AX,3030h
    MOV BX,OFFSET Result
    MOV byte ptr[BX],5
    MOV byte ptr[BX+4],'$'
    MOV byte ptr[BX+3],AH
    MOV byte ptr[BX+2],AL

    MOV DX,BX
    ADD DX,02
    MOV AH,09H
    INT 21H
    POP DX
    ADD DX,1
LOOP L2

;If the number is equal to 20 come here, ->
; Every step is repeated here just to change 6D to 12D

L3:
    ADD AX,12D
    XOR AH,AH

    ROR AX,1
    ROR AX,1
    ROR AX,1
    ROR AX,1

    SHR AH,1
    SHR AH,1
    SHR AH,1
    SHR AH,1

    ADC AX,3030h
    MOV BX,OFFSET Result
    MOV byte ptr[BX],5
    MOV byte ptr[BX+4],'$'
    MOV byte ptr[BX+3],AH
    MOV byte ptr[BX+2],AL

    MOV DX,BX
    ADD DX,02
    MOV AH,09H
    INT 21H

コードを何度も繰り返すのではなく、関数を作成し、if/else (ジャンプ) を使用して目的の出力を取得する適切な方法はありますか?

疑似コード:

VAR = 6
IF Number is > 9
ADD AX,VAR
Else IF Number is > 19
ADD AX,(VAR*2)
ELSE IF NUMBER is > 29
ADD AX,(VAR*3)
4

2 に答える 2

3

0 ... 20 をASCII文字として出力したいだけですか?数字は「0」から「9」の 0x30 ... 0x39 として識別されることを理解しているように見えるので、整数除算を使用して 10 桁の文字を生成できます。

私は通常 C で作業しますが、これらはすべて基本的な操作であり、関数呼び出しがないため、アセンブラーへの変換はそれほど複雑ではありません。

int i_value = 29;
int i_tens = i_value/10; //Integer division! 29/10 = 2, save for later use
char c_tens = '0' + i_tens;
char c_ones = '0' + i_value-(10*i_tens); // Subtract N*10 from value

出力は になりますc_tens = 0x32, c_ones = 0x39。レジスタのペアを使用して、ループ内でこれを非常に簡単にラップできるはずです。

疑似コード

regA <- num_iterations //For example, 20
regB <- 0 //Initialize counter register

LOOP:
    //Do conversion for the current iteration.
    //Manipulate bytes for output as necessary.
    regB <- regB +1
    branch not equal regA, regB LOOP
于 2012-09-23T20:28:21.180 に答える
1

次のコードは、0 から 99 までカウントします (ax には ASCII 番号が含まれます)。

count proc
      mov cx, 100 ; loop runs the times specified in the cx register
      xor bx, bx ; set counter to zero
      print:
      mov ax, bx
      aam ; Converts binary to unpacked BCD
      xor ax, 3030h ; Converts upacked BCD to ASCII
      ; Print here (ax now contains the numer in ASCII representation)
      inc bx ; Increase counter
      loop print
      ret
count endp
于 2012-10-17T23:15:39.467 に答える