2016-03-04 224 views
0

假设1A(十六进制中的26)存储在EAX寄存器中。我怎样才能将其转换为十进制,然后将其显示为输出?有没有Irvine的功能呢,还是有另一种方法呢?x86汇编语言:如何将十六进制寄存器值打印为十进制输出?

+0

可能重复的[MASM:整数字符串使用std和stosb](http://stackoverflow.com/questions/29065108/masm-整数到字符串使用std和stosb) – zx485

+0

您可能想使用Irvine32函数'WriteInt'来写有符号整数或'WriteDec'来写无符号整数。这两个函数都将_EAX_中的值作为要打印的值。所以你可以做'mov eax,42''调用WriteInt',那将在控制台上显示42 –

回答

0

我不知道如果欧文图书馆包含这样的事情;我从来没有使用过这个库。

(我希望我不会解决某人家庭作业,只是说...)

这是一个非常简单的练习以纯x86汇编,采用重复除法/模量。在C中,基本算法看起来像这样:

void ConvertToDecimal(unsigned int n, char *output) 
{ 
    char buffer[16]; 
    char *dest = buffer + 15; 

    /* Perform repeated division, which outputs digits in reverse 
     order. But we put them in the buffer in reverse order, too, 
     so they end up coming out in the correct order overall. */ 
    *--dest = '\0'; 
    if (n == 0) { 
     *--dest = '0'; 
    } 
    else { 
     while (n > 0) { 
      *--dest = n % 10 + '0'; 
      n /= 10; 
     } 
    } 

    /* Copy the generated digits to the output. */ 
    strcpy(output, dest); 
} 

程序集版本实际上是做同样的基本技术的问题。 (并且从C语言中的问题的高级描述开始,然后将该解决方案移植到组装中是解决类似问题的一种方法。)

因此,从eax中的数字开始,并输出指针在ebx目标缓冲区,你最终是这样的:

ConvertToDecimal: 
    push edi    ; Preserve registers we're going to use. 

    sub esp, 16    ; Make room for a local buffer on the stack. 
    mov edi, esp   ; edi will act like 'dest' does in the C version. 
    mov ecx, 10    ; We'll be repeatedly dividing by 10, and the 
          ; div instruction doesn't let you just say 'div 10'. 

    dec edi 
    mov byte ptr [edi], 0 ; Write the trailing '\0'. 

    cmp eax, 0    ; If n == 0... 
    ja l1     ; If it's more than zero, run the loop. 

    dec edi 
    mov byte ptr [edi], '0' ; Write a '0' to the output. 
    jmp l2 

    ; Main division loop. 

l1: xor edx, edx   ; Zero out edx in preparation for the division. 
    div ecx     ; Divide and modulus edx|eax by 10. 
          ; eax gets the quotient; edx gets the remainder. 

    add edx, '0'   ; Change edx from 0-9 to '0'-'9'. 

    dec edi 
    mov byte ptr [edi], dl ; Write the next digit, which is now in dl. 

    cmp eax, 0 
    ja l1     ; Go back and do it again until we reach zero.   

    ; Copy the result to the destination. 

l2: mov al, byte ptr [edi] ; Read the next character from edi... 
    inc edi 
    mov byte ptr [ebx], al ; ...and write that character to ebx. 
    inc ebx 

    cmp al, 0    ; Copy until we reach the trailing 0 byte. 
    jnz l2 

    mov eax, ebx   ; As a bonus for the caller, set the return register 
    dec eax     ; to where we wrote the last byte. 

    add esp, 16    ; Clean up the buffer on the stack. 
    pop edi     ; Restore the registers we used. 

    ret      ; And we're done. 

为了记录在案,我还没有运行上面的代码,但它应该工作。

至于显示它作为输出,你需要任何库函数或中断你可以用来打印一个字符串。在DOS的日子里,我只是一再呼吁int 10h ...