用汇编语言创建函数(TASM)

时间:2012-09-23 19:28:06

标签: function assembly x86 tasm

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

打印前九个数字是绝对正确的,因为十六进制和十进制代码是相同的,但从第10个数字我必须将每个数字转换为适当的代码然后转换它并将其存储到字符串并最终显示它< / p>

即,

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(跳转)来获得所需的输出而不是一次又一次地重复代码?

PSEUDO CODE:

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)

2 个答案:

答案 0 :(得分:3)

所以你只想打印0 ... 20作为ASCII个字符?看起来您理解数字被标识为“0”到“9”的0x30 ... 0x39,因此您可以使用整数除法来生成十位数的字符:

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

答案 1 :(得分: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