如何从C库打印照片,无需在printf的汇编级编程的整数? [英] How do I print an integer in Assembly Level Programming without printf from the c library?

查看:166
本文介绍了如何从C库打印照片,无需在printf的汇编级编程的整数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

谁能告诉我的纯粹组装的code为十进制格式显示寄存器的值?请不要建议使用printf的黑客,然后用gcc编译。

Can anyone tell me the purely assembly code for displaying the value in a register in decimal format? Please don't suggest using the printf hack and then compile with gcc.

说明:

好吧,我做了一些研究和一些试验用NASM和揣摩,我可以用printf函数C库打印一个整数。我这样做是在编译的GCC编译器的目标文件,一切工作不够公平。

Well, I did some research and some experimentation with NASM and figured I could use the printf function from the c library to print an integer. I did so by compiling the object file with the GCC compiler and everything works fair enough.

不过,我要实现的是打印存储在任何寄存器中的小数形式的值。

However, what I want to achieve is to print the value stored in any register in the decimal form.

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

I did some research and figured the interrupt vector 021h for DOS command line can display strings and characters whilst either 2 or 9 is in the ah register and the data is in the dx.

结论:

我发现的例子中无一例出现如何不使用C库的printf显示十进制格式的登记册的内容价值。有谁知道如何在组装这样做吗?

None of the examples I found showed how to display the content value of a register in decimal form without using the C library's printf. Does anyone know how to do this in assembly?

推荐答案

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

You need to write a binary to decimal conversion routine, and then use the decimal digits to produce "digit characters" to print.

您必须假设的东西,某个地方,将打印您所选择的输出设备上的字符。调用此子程序print_character假设它需要一个字符code在EAX和preserves所有的寄存器。(如果您还没有这样的函数,你有一个额外的问题,这应该是一个不同的问题的基础上)。

You have to assume that something, somewhere, will print a character on your output device of choice. Call this subroutine "print_character"; assumes it takes a character code in EAX and preserves all the registers.. (If you don't have such a subroutine, you have an additional problem that should be the basis of a different question).

如果你有二进制code一个数字(例如,从0-9的值)在寄存器(例如,EAX),您可以在值中加入ASCII $转换为数字字符C $ c代表零字寄存器。这很简单,只要:

If you have the binary code for a digit (e.g., a value from 0-9) in a register (say, EAX), you can convert that value to a character for the digit by adding the ASCII code for the "zero" character to the register. This is as simple as:

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

您可以调用print_character打印的数字字符code。

You can then call print_character to print the digit character code.

要输出的任意值,则需要摘下数字,并打印出来。

To output an arbitrary value, you need to pick off digits and print them.

摘数字根本要求与10的幂的工作。它是最简单的有十一个功率工作,例如10本身。试想一下,我们有一个除以10例程在EAX了一个值,并产生了一个EDX商和在EAX其余部分。我把它作为一个练习,你找出如何实现这样一个程序。

Picking off digits fundamentally requires working with powers of ten. It is easiest to work with one power of ten, e.g., 10 itself. Imagine we have a divide-by-10 routine that took a value in EAX, and produced a quotient in EDX and a remainder in EAX. I leave it as an exercise for you to figure out how to implement such a routine.

然后用正确的想法简单的常规是产生一个数字的所有数字的值可能。 32位寄存器用于存储值4十亿,所以你可能会得到印10位。所以:

Then a simple routine with the right idea is to produce one digit for all digits the value might have. A 32 bit register stores values to 4 billion, so you might get 10 digits printed. So:

         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

这工作......但打印的数字按相反的顺序。哎呀!好了,我们可以利用产生的下推堆栈来存储数字,然后以相反的顺序弹出他们关闭:

This works... but prints the digits in reverse order. Oops! Well, we can take advantage of the pushdown stack to store digits produced, and then pop them off in reverse order:

         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

作为练习留给读者:SUP preSS前导零。此外,由于我们正在写数字字符到内存中,而不是将其写入到协议栈,我们可以将其写入缓冲器,然后打印缓冲区的内容。同时作为练习留给读者。

Left as an exercise to the reader: suppress leading zeros. Also, since we are writing digit characters to memory, instead of writing them to the stack we could write them to a buffer, and then print the buffer content. Also left as an exercise to the reader.

这篇关于如何从C库打印照片,无需在printf的汇编级编程的整数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆