这是家庭作业吗?
比特就是比特。位,字节,字,双字,这些是硬件术语,指令集/汇编器将参考。十六进制、十进制、八进制、无符号、有符号、字符串、字符等都是编程语言的表现形式。同样.text、.bss、.data等也是软件工具的体现,指令集不关心一个地址是.data,一个是.text,无论哪种方式都是相同的指令。所有这些编程语言事物的存在是有原因的,有时是非常好的原因,但在尝试解决这个问题时不要感到困惑。
要将位转换为人类可读的 ascii,首先需要了解您的 ascii 表、位运算符、和、或、逻辑移位、算术移位等。再加上加载和存储等。
从数学上考虑从寄存器/内存中的某个数字到 ascii hex 需要什么。说 0x1234,即 0b0001001000110100。对于人类阅读它,是的,您需要将它放入一个字符串中,因为缺少更好的术语,但您不一定需要在相邻的内存位置存储四个字符加上一个空值才能对其进行处理。这取决于您的输出功能。通常基于字符的输出实体归结为多次调用的某种类型的单个 output_char()。
您可以转换为字符串,但这需要更多的工作,因为您计算的每个 ascii 字符都会立即调用某种基于单字符的输出函数。putchar() 是字节输出字符类型函数的示例。
因此,对于二进制文件,您希望一次检查一位并创建一个 0x30 或 0x31。对于八进制,一次 3 位并创建 0x30 到 0x37。十六进制一次基于 4 位。
Hex有个问题就是我们要使用的16个字符在ascii表中找不到相邻的。因此,根据您的偏好或要求,您使用 0x30 到 0x39 表示 0 到 9,但使用 0x41 到 0x46 或 0x61 到 0x66 表示 A 到 F。因此,对于每个 nybble,您可能会使用 0xF 与 9 进行比较并添加 0x30 或 0x37(10+0x37 = 0x41、11+0x37 = 0x42 等)。
从寄存器中的位转换为二进制的 ascii 表示。如果内存中的位为 1,则显示 1(0x31 ascii),该位为 0,则显示 0(ascii 中的 0x30)。
void showbin ( 无符号字符 x )
{
无符号字符 ra;
对于(ra=0x80;ra;ra>>=1)
{
if(ra&x) output_char(0x31); 否则输出字符(0x30);
}
}
使用上面的 unsigned char 似乎是合乎逻辑的,但 unsigned int 取决于目标处理器,可以生成更好(更干净/更快)的代码。但那是另一个话题
上面的内容在汇编程序中可能看起来像这样(故意不使用 x86)
...
移动 r4,r0
mov r5,#0x80
最佳:
tst r4,r5
moveq r0,#0x30
移动 r0,#0x31
bl output_char
mov r5,r5, lsr #1
cmp r5,#0
顶部
...
展开更容易编写并且会更快一些,权衡是使用更多的内存
...
tst r4,#0x80
moveq r0, #0x30
移动 r0,#0x31
bl output_char
tst r4,#0x40
moveq r0, #0x30
移动 r0,#0x31
bl output_char
tst r4,#0x20
moveq r0, #0x30
移动 r0,#0x31
bl output_char
...
假设您有 9 位数字并想转换为八进制。一次取三位(记住人类从左到右阅读,所以从高位开始)并添加 0x30 以获得 0x30 到 0x37。
...
移动 r4,r0
移动 r0,r4,lsr #6
和 r0,r0,#0x7
添加 r0,r0,#0x30
bl output_char
移动 r0,r4,lsr #3
和 r0,r0,#0x7
添加 r0,r0,#0x30
bl output_char
和 r0,r4,#0x7
添加 r0,r0,#0x30
bl output_char
...
十六进制的单个(8 位)字节可能如下所示:
...
移动 r4,r0
移动 r0,r4,lsr #4
和 r0,r0,#0xF
cmp r0,#9
添加 r0,r0,#0x37
添加 r0,r0,#0x30
bl output_character
和 r0,r4,#0xF
cmp r0,#9
添加 r0,r0,#0x37
添加 r0,r0,#0x30
bl output_character
...
进行从 1 到 N 的循环,将该值存储在内存中并从内存 (.data) 中读取它,以十六进制输出:
...
mov r4,#1
str r4,my_variable
...
最佳:
ldr r4,my_variable
移动 r0,r4,lsr #4
和 r0,r0,#0xF
cmp r0,#9
添加 r0,r0,#0x37
添加 r0,r0,#0x30
bl output_character
和 r0,r4,#0xF
cmp r0,#9
添加 r0,r0,#0x37
添加 r0,r0,#0x30
bl output_character
...
ldr r4,my_variable
添加 r4,r4,#1
str r4,my_variable
cmp r4,#7 ;说N是7
顶部
...
我的变量.word 0
如果您有足够的寄存器,则保存到 ram 有点浪费。尽管使用 x86,您可以直接在内存上进行操作,而不必通过寄存器。
x86 与上述 (ARM) 汇编器不同,因此留给读者练习以计算出等价物。关键是,它是移位、加、加,把它分解成基本的步骤,指令自然地从那里掉出来。