如何在程序集8086中显示十进制的64位数字

时间:2014-05-26 22:52:21

标签: assembly overflow emulation x86-16 divide

我正在完成一项任务,而且我一直在分流溢出 它给出了一个错误,因为我将64位数DX AX除以32位数。答案不适合AX,因此会出错。

有没有办法克服这种溢出?我想将这个数字转换成十进制数,所以我试图将它除以10.

3 个答案:

答案 0 :(得分:2)

从edx = 0开始,eax =被除数的高位。除以10,eax将成为下一个循环的高分红,所以保存它。 edx将具有余数,用于下一个除法:eax =被除数的低位。除以10,eax将是下一个循环的较低红利,所以保存它。 edx将是64位被除数的余数除以10,这将是该数字的最低有效十进制数字。重复循环以相反的顺序获取数字。

在回应下面的评论时,假设64位数字在EDI中:ESI(高:低):

        mov     ecx,10
loop0:  xor     edx,edx         ;divide high order by 10
        mov     eax,edi
        div     ecx
        mov     edi,eax
        mov     eax,esi         ;divide low  order by 10
        div     ecx
        mov     esi,eax
;                               ;at this point edx contains one decimal digit
;       ...                     ;store the digit and continue with the loop

答案 1 :(得分:1)

上的DI:SI:CX:BX中显示64位数字

步骤1.计算数字

这需要使用从64位数字的最高有效字开始的一系列分区。每个部门的剩余部分将在下一个部门重新使用。

  mov  bp, 10  ;Constant divider 10
  push bp      ;Will signal the end of the PUSHed remainders
Next:
  xor  dx, dx
  xchg ax, di  ;Most Significant Word is in DI
  div  bp      ;Divide Word3
  xchg di, ax
  xchg ax, si
  div  bp      ;Divide Word2
  xchg si, ax
  xchg ax, cx
  div  bp      ;Divide Word1
  xchg cx, ax
  xchg ax, bx  ;Least Significant Word is in BX
  div  bp      ;Divide Word0
  mov  bx, ax

  push dx      ;Every remainder is [0,9]

  or   ax, cx  ;OR all quotients together
  or   ax, si
  or   ax, di
  jnz  Next    ;Repeat while 64-bit number not zero

请注意,xchg指令用于减少代码大小!

步骤2.显示数字

要显示我认为这是在DOS上运行的字符 应该真的很容易适应另一个操作系统......

  pop  dx      ;This is digit for sure
More:
  add  dl, '0' ;Convert from remainder [0,9] to character ["0","9"]
  mov  ah, 02h
  int  21h     ;DisplayCharacter
  pop  dx
  cmp  dx, bp  ;Repeat until it was the 'signal (bp=10)' that was POPed
  jb   More

答案 2 :(得分:0)

从rcgldr获得灵感

这是如何在8086中完成的,因为8086中的所有寄存器都是16位

                                ;here we have a 64bit number in bx:cx:di:si
loop0:  xor dx,dx
        mov ax,si               ;divide highes order by 10
        div diver
        mov si,ax
        mov ax,di               ;divide high order by 10
        div diver
        mov di,ax
        mov ax,cx               ;divide low oreder by 10
        div diver
        mov cx,ax
        mov ax,bx               ;divide lowest order by 10
        div diver
        mov bx,ax
                                ;right now we have the wanted number in dx
        mov temp,si             ;keep value of si for later
        mov si,[bp+4]           ;make si point to wanted string
        add si,18               ;move to end of string
        sub si,counter          ;move back the amount of times used
        add dx,'0'
        mov byte ptr [si],dl
        inc counter
        mov si,temp             ;put back saved value in si and go again
        cmp ax,0
        jne loop0
        mov counter,0           ;reset counter

我试图解决类似问题2天!!直到我读到rcgldr的回答。谢谢!唯一的区别是我需要在386环境中将64位数除以10而不是8086,但它完全相同 因为你的问题帮助我,我在8086年为你写了这段代码。

希望它有所帮助...