此问题已在此处有答案:
How to convert a binary integer number to a hex string?(3个答案)
两年前关闭。
我正在努力学习NASM汇编,但我似乎正在努力与什么似乎简单的高级语言。
我使用的所有教科书都在讨论如何使用字符串--事实上,这似乎是他们最喜欢的东西之一。打印hello world,从大写改为小写等等
然而,我试图了解如何在NASM程序集中递增和打印十六进制数字,不知道如何继续。例如,如果我想用十六进制打印#1 - n,如果不使用C库(我能找到的所有引用都使用了C库),我该怎么做呢?
我的主要想法是在。数据部分,我会继续增加。但是如何从这个位置提取十六进制值呢?我似乎需要先把它转换成字符串。...
任何建议或示例代码将不胜感激。
4条答案
按热度按时间w1e3prcc1#
首先编写一个简单的例程,它取一个nybble值(0..15)作为输入,并输出十六进制字符('0 '。“9”,“A”,“F”)。
接下来编写一个例程,它以一个字节值作为输入,然后调用上面的例程两次,输出2个十六进制字符,即:即每个半字节一个。
最后,对于一个N字节的整数,你需要一个例程来调用第二个例程N次,每个字节一次。
您可能会发现,首先用伪代码或HLL(如C)来表达这一点很有帮助,然后再考虑如何将其转换为asm,e。g的。
ao218c7q2#
这是家庭作业吗
比特就是比特。位、字节、字、双字,这些都是硬件术语,是指令集/汇编程序将要引用的。十六进制、十进制、八进制、无符号、有符号、字符串、字符等是编程语言表现形式。同样。文本,。bss、.data等也是软件工具的表现形式,指令集不关心一个地址是否存在。数据和一个存在。文本,无论哪种方式都是相同的指令。所有这些编程语言的东西存在是有原因的,有时候是非常好的原因,但是在试图解决这个问题时不要感到困惑。
要从位转换为人类可读的ascii,首先需要知道ascii表,以及按位运算符,and,or,逻辑移位,算术移位等加上装载和存储和其他东西。
从数学上想一想,从寄存器/内存中的某个数字转换成ascii十六进制需要什么。比如说0x 1234,它是0 b 0001001000110100。对于一个人来说,阅读它,是的,你需要把它变成一个字符串,因为没有更好的术语,但你不一定需要在相邻的内存位置存储四个字符加上一个null,以便对它做一些事情。这取决于你的输出函数。通常,基于字符的输出实体可以归结为一个被多次调用的outputchar()。
你可以转换成一个字符串,但这是更多的工作,对于每个ascii字符,你计算调用某种基于单个字符的输出函数。putchar()是字节输出字符类型函数的一个示例。
因此,对于二进制,您需要一次检查一位并创建0x 30或0x 31。对于八进制,一次3位,并创建0x 30到0x 37。十六进制是基于一次4位。
Hex有一个问题,我们想要使用的16个字符在ascii表中找不到彼此相邻的。因此,您可以使用0x 30到0x 39来表示0到9,而使用0x 41到0x 46或0x 61到0x 66来表示A到F,这取决于您的偏好或要求。因此,对于每个半字节,您可以与0xF进行AND,与9进行比较,并添加0x 30或0x 37(10+ 0x 37 = 0x 41,11+ 0x 37 = 0x 42等)。
从寄存器中的位转换为二进制的ascii表示。如果存储器中的位是1,则显示1(0x 31 ascii),如果存储器中的位是0,则显示0(0x 30 ascii)。
使用上面的unsigned char似乎是合乎逻辑的,但是根据目标处理器的不同,unsigned int可以产生更好(更干净/更快)的代码。但那是另一个主题了
上面可以看起来像汇编程序中这样(故意不使用x86)
Unrolled更容易写,速度也更快,但代价是占用更多内存
假设您有9位数字,并希望转换为八进制。一次取三位(记住人类从左到右阅读,所以从高位开始),并添加0x 30以获得0x 30到0x 37。
十六进制中的单个(8位)字节可能看起来像:
从1到N进行循环,将该值存储在内存中并从内存中阅读(.数据),以十六进制输出:
如果你有足够的寄存器,保存到ram是有点浪费。虽然使用x86,您可以直接在内存上操作,而不必通过寄存器。
x86与上面的(ARM)汇编程序不一样,所以读者可以通过练习来计算出等价物。关键是,它是转移,anding,和添加那个物质,把它分解成基本的步骤,指令就从那里自然地落出来了。
vom3gejh3#
快速脏GAS宏
使用方法:
使用
<>
是因为.altmacro
:Gas altmacro macro with a percent sign in a default parameter fails with "% operator needs absolute expression"结果:
%al
包含0x31,即ASCII中的'1'
%bl
包含0x41,即ASCII中的'A'
现在你可以用
%al
和%bl
,e做任何你想做的事情。例如:jhiyze9q4#
英特尔语法。这是从我的 Bootstrap ,但你应该能够得到的想法。