1

我想使用循环打印前 20 个数字。

打印前九个数字绝对没问题,因为十六进制和十进制代码是相同的,但是从第 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 (jumps) 来获得所需的输出,而不是一次又一次地重复代码?

伪代码:

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字符?看起来您了解数字被标识为 0x30 ... 0x39 表示“0”到“9”,因此您可以使用整数除法来生成十位数字的字符:

我通常使用 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 回答