assembly - 如何在没有 c 库中的 printf 的情况下在汇编级编程中打印整数? (itoa,整数到十进制的 ASCII 字符串)

标签 assembly x86 integer output nasm

谁能告诉我以十进制格式显示寄存器中值的纯汇编代码?请不要建议使用 printf hack,然后使用 gcc 进行编译。

描述:

好吧,我对 NASM 进行了一些研究和一些实验,并认为我可以使用 c 库中的 printf 函数来打印一个整数。我通过使用 GCC 编译器编译目标文件来做到这一点,一切正常。

然而,我想要实现的是将存储在任何寄存器中的值以十进制形式打印。

我做了一些研究,发现 DOS 命令行的中断向量 021h 可以显示字符串和字符,而 2 或 9 在 ah 寄存器中,数据在 dx 中。

结论:

我找到的所有示例都没有显示如何在不使用 C 库的 printf 的情况下以十进制形式显示寄存器的内容值。有谁知道如何在 assembly 中做到这一点?

最佳答案

你需要写一个二进制到十进制的转换例程,然后用十进制数字产生“数字字符”来打印。

您必须假设某处某物会在您选择的输出设备上打印一个字符。调用这个子程序“print_character”;假设它在 EAX 中接受一个字符代码并保留所有寄存器。(如果你没有这样的子程序,你会有一个额外的问题,它应该是另一个问题的基础)。

如果您在寄存器(比如 EAX)中有一个数字的二进制代码(例如,一个 0-9 的值),您可以通过添加“零”字符到寄存器。这很简单:

       add     eax, 0x30    ; convert digit in EAX to corresponding character digit

然后您可以调用 print_character 来打印数字字符代码。

要输出任意值,您需要选择数字并打印出来。

提取数字基本上需要使用 10 的幂。使用 10 的一次幂是最简单的,例如 10 本身。想象一下,我们有一个除以 10 的例程,它在 EAX 中取一个值,在 EDX 中产生一个商,在 EAX 中产生一个余数。我把它留作练习,让您了解如何实现这样的例程。

然后一个具有正确想法的简单例程是为该值可能具有的所有数字生成一个数字。一个 32 位寄存器存储 40 亿的值,所以你可能会打印 10 位数字。所以:

         mov    eax, valuetoprint
         mov    ecx, 10        ;  digit count to produce
loop:    call   dividebyten
         add    eax, 0x30
         call   printcharacter
         mov    eax, edx
         dec    ecx
         jne    loop

这行得通...但会以相反的顺序打印数字。哎呀!好吧,我们可以利用下推堆栈来存储生成的数字,然后以相反的顺序将它们弹出:

         mov    eax, valuetoprint
         mov    ecx, 10        ;  digit count to generate
loop1:   call   dividebyten
         add    eax, 0x30
         push   eax
         mov    eax, edx
         dec    ecx
         jne    loop1
         mov    ecx, 10        ;  digit count to print
loop2:   pop    eax
         call   printcharacter
         dec    ecx
         jne    loop2

留给读者作为练习:取消前导零。此外,由于我们正在将数字字符写入内存,而不是将它们写入堆栈,我们可以将它们写入缓冲区,然后打印缓冲区内容。也留给读者作为练习。

关于assembly - 如何在没有 c 库中的 printf 的情况下在汇编级编程中打印整数? (itoa,整数到十进制的 ASCII 字符串),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57227410/

相关文章:

performance - 我可以在 x86/x86_64 上自动递增 16 位计数器吗?

c - 为什么C在调用汇编函数时不将指针压入堆栈?

linux - 在汇编中将用户输入的十六进制转换为十进制

algorithm - 在 DWORD 数组中查找最重要的 DWORD

linux - 如何使用 NASM for x86-64bit 读写文件

assembly - 减数较大时如何设置进位标志?

assembly - 返回堆栈中的指令指针

Java:字节到 float /整数

SQL:如果我的最大值是 255,使用 tinyint 而不是 Integer 是否有效?

jquery - 计算 int 中的字符数量