转换十六进制/十进制数(Assembly-TASM)

时间:2012-09-21 19:00:47

标签: assembly x86 tasm

我试图简单地在序列中打印数字,即

1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20

使用Loop, 首先我将每个数字转换为Hexa打印,然后将其重置为十进制增量1,然后打印下一个直到数字等于9, 当数字等于9时,我使用DAA来简化数字,在旋转和移动数字后,我最终将结果存储在字符串中。

直到16时输出才正常,但在16之后,序列重复,

期望的输出:

1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20

当前输出  1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,11,12,13,14,15

为什么会这样呢???

这是我的代码,

MOV CX,20 ;Number of Iterations


MOV DX,1



L1:
    PUSH DX
    ADD DX,30H  
    MOV AH,02H        ;PRINT Content of DX
    INT 21H
    POP DX
    ADD DX,1
    CMP DX,09d        ;If number is Greater than 9 jump to L2   
    JA L2
LOOP L1


    L2: 
        PUSH DX
        MOV AX,DX
        DAA           ;Convert to the Decimal
        XOR AH,AH         ;SET AH to 0000


        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           ; Length of the String
        MOV byte ptr[BX+4],'$'       ;5th position of string , $=Terminator
        MOV byte ptr[BX+3],AH        ;2nd Number onto 4th position
        MOV byte ptr[BX+2],AL        ;3rd number onto 3rd Position 

        MOV DX,BX
        ADD DX,02     ;1st 2 positions of String are type of string and    
                                  length respectively 
        MOV AH,09H ;to print the string
        INT 21H         

        POP DX      
        ADD DX,1

    LOOP L2

MOV AH,4CH  ;Return control to the DOS
INT 21H
P.S:我从这张图表中获得了解数字的帮助。

http://www.cheat-sheets.org/saved-copy/ascii.png

3 个答案:

答案 0 :(得分:4)

8086代码只允许立即为1(或cl)进行移位和旋转计数。要启用286代码,请告诉文件顶部的Tasm“.286”。这是猜测。

我记得以前用来在al:

打印一个两位数字的方式
aam
add ax, 3030h
xchg al, ah
int 29h
mov al, ah
int 29h

答案 1 :(得分:3)

试一试,虽然我不确定,但我无法快速测试。

但是我不建议使用两个循环,而是建议在整个数字中使用一个循环。

此外,我感觉问题与DAA指令有关,我不习惯,因为它在64位模式下不受支持。

无论如何,这就是我要做的事情:

      mov  cx,20
      mov   al,1
      mov   bl,10      ; divisor
      mov   bp,offset Result ; no need to load this in the loop!!!

L1:   mov   dx,ax      ; save to register, not to stack
      cmp   ax,09d
      ja    L2         ; number has two digits
      add   al,30h     ; ASCII addend

      ; insert your output code here

      jmp   L3         ; jump over the two digit code
L2:   xor   ah,ah
      div   bl         ; divides AX by ten (no rotate or shift needed)
                       ; quotient in AL, remainder in AH (correct order for little endian)
      add   ax,3030h

      ; insert your output code here (note that the buffer/string address is loaded to BP)

L3:   mov   ax,dx
      inc   ax
      loop  L1

      ; done

如果您不介意一位数字的前导零,那就更容易了。

div指令可能比daarorshr更贵,但你的四轮旋转/转换会更糟: - /

(正如我所说,我无法尝试......让你开放......如果它不起作用,只需回复。)

-

[更新:

另一种方法,特别是将div放在这个简单的数字分离情况下,将增加6到数字大于9(即10d = 0ah - (+ 6) - > 16d = 10h ;这是daa也可以做的事情,那么你就可以使用之前使用的旋转/移位组合。

更好的是添加246,然后添加到AX,之后您可以简单地使用ror ax,8(或rol - 在这种情况下无关紧要),i。即10d = 0ah - (+ 246) - > 256d = 100h,以及15d = 0fh - (+ 246) - > 261 = 105h。将它分别旋转为0001h或0501h,加3030h,就完成了。

/更新]

[update level =“2”

有趣的是......我实际上打算在第一级更新中编写它,但忘记了它:而不是rol ling by 8,或者 - 如果你的TASM真的不支持{{1通过立即 - 八次滚动一次,您当然也可以使用rol指令,它在寄存器之间交换值,在这种情况下

xchg

将完成交换这两个寄存器内容的工作。

还有一条 xchg al,ah 指令用于反转寄存器中的字节顺序,但它显然只适用于32位宽的寄存器。

/更新]

答案 2 :(得分:0)

.model small  
 .stack 100  
 .code  
      mov ax, 0ffffh            ; hex number to find it's bcd  
      mov      bx, 0000  
      mov      dh, 0  
 l9 :     cmp     ax, 10000     ; if ax>10000  
      jb      l2  
      sub      ax, 10000        ; subtract 10000  
      inc      dh               ; add 1 to dh  
      jmp      l9  
 l2 :     cmp      ax, 1000     ; if ax>1000  
      jb      l4  
      sub      ax, 1000  
      add      bx, 1000h        ; add 1000h to result  
      jmp      l2  
 l4 :     cmp      ax, 100      ; if ax>100  
      jb      l6  
      sub      ax, 100  
      add      bx, 100h         ; add 100h to result  
      jmp      l4  
 l6 :     cmp      ax, 10       ; if ax>10  
      jb      l8  
      sub      ax, 10  
      add      bx, 10h          ; add 10h to result  
      jmp      l6  
 l8 :     add      bx, ax       ; add remainder   
                                ; to result  
      mov      ah, 02            
      mov      cx, 0204h        ; Count to display   
                                ; 2 digits  
      go:      rol dh, cl  
      mov      dl, dh  
      and      dl, 0fh  
      add      dl, 30h          ; display 2 msb digits       
      int      21h  
      dec      ch  
      jnz      go  
      mov      ch, 04h          ; Count of digits to be   
                                ; displayed  
      mov      cl, 04h          ; Count to roll by 4 bits  
 l12:     rol      bx, cl       ; roll bl so that msb   
                                ; comes to lsb                  
      mov      dl, bl           ; load dl with data to be   
                                ; displayed  
      and      dl, 0fH          ; get only lsb  
      cmp      dl, 09           ; check if digit is 0-9 or letter A-F      
      jbe      l14  
      add      dl, 07           ; if letter add 37H else only add 30H  
 l14:     add      dl, 30H  
      mov      ah, 02           ; Function 2 under INT 21H      (Display character)  
      int      21H  
      dec      ch               ; Decrement Count  
      jnz      l12  
      mov      ah, 4cH          ;  Terminate Program  
      int      21H  
 end