如何从 4 位十六进制转换为 7 位 ASCII?

Posted

技术标签:

【中文标题】如何从 4 位十六进制转换为 7 位 ASCII?【英文标题】:How to convert from 4-bit hexadecimal to 7-bit ASCII? 【发布时间】:2012-08-16 18:07:36 【问题描述】:

任务是通过编写一个可以在4位十六进制和7位ASCII之间转换的子程序来学习汇编编程。起初我不知道,但经过一些研究,我可以做出努力并绘制流程图并制作程序,但这并不完全正确,所以我请求您的指导来帮助我解决这个问题。

实际的作业文本是这样的:

HA 3.1。绘制子程序转换 4 位的流程图 十六进制值转换为相应的 7 位 ASCII 码。查看完整的 hexasc 规格如下。示例:二进制 0010(十六进制 数字 2) 被转换为 011 0010('2' 的 ASCII 码)。其他 示例:二进制 1011(十六进制数字 B)转换为 100 0010 (“B”的 ASCII 代码)确保您的子程序已记录在案 根据我们的要求。

HA 3.2。使用 Nios II IDE 中的 labwork 项目,创建一个新的 名为 hexasc.s 的文件

HA 3.3。在文件 hexasc.s 中,编写一个名为 hexasc 的子程序,即 将 4 位十六进制值转换为相应的 7 位 ASCII 码。

我为这个程序画了一个流程图:

我尝试过的程序是这样的,但我怀疑它不符合规范:

        .global main 

        .text
        .align 2

main:   movi r8, 0x09
        movi r9, 0x0f

        andi r4, r4, 0x0f

        bgt r8, r4, L1  

        movi r2, 0x1e
        add r2, r2, r4  
        andi r2, r2, 0xff

        movia   r2,putchar
        br  L2  

L1:     movi r2, 0x29   
        add r2, r2, r4
        andi r2, r2, 0xff

        movia   r2,putchar

L2:  .end 

你能帮我开发和解决这个任务吗?时间很充裕,一个月后才到期。

更新

在此处看到流程图不正确的评论后,我进行了必要的调整:

我还想讨论一下这个算法在十六进制和 ASCII 之间转换是如何正确的。

更新/编辑

这是完整的程序。

.global hexasc 

        .text
        .align 2

hexasc: movi r8, 0x09
        movi r9, 0x0f
        andi r4, r4, 0x0f #keep only 4 bits
        bgt r4, r8, L1  #is x>9?
        movi r2, 0x30
        add r2, r2, r4  
        andi r2, r2, 0xff
        ret  

L1:     movi r2, 0x37
        add r2, r2, r4
        andi r2, r2, 0xff
        ret

【问题讨论】:

图表在数字上不正确。 ASCII(x) = x + 30H(48d) 如果 0 我很确定您应该屏蔽并只保留最后四个 ,而不是字节。您的代码正确地做到了。 a=h+((h>9)?55:49) 有什么不清楚的地方?这是修正后的图表现在描述的内容,除了公式必须有 48 而不是 49。 我不知道您使用的是什么汇编程序,但它肯定可以处理字符文字而不仅仅是数字。要将 5 转换为 ASCII,只需在字符 '0' 上加 5。让汇编器来评估'0' 是 30H 和 30H + 5 是 35H,即 ASCII 字符“5”。如果你这样做,你的代码是自我记录的,而不是乱七八糟的数字。 我们在 SO 看到的无数关于如何转换十进制、二进制、十六进制、ascii 的问题。这个问题值得回答,因为您实际上已经尝试过,经过深思熟虑,理解了数字系统和位表示,只是出现了一个细微的数学错误。 【参考方案1】:

流程图中的一些错误

1.屏蔽并只保留最后四个字节 --> 2.决定0<x<9 --> 0<=x<=9 3.Decision 9<x<15 --> 9<x<=15(也是多余的!)

程序

.global hexasc 

    .text
    .align 2

hexasc: movi r8, 0x09
        andi r4, r4, 0x0f #keep only 4 bits
        movi r2, 0x37
        bgt r4, r8, L1  #is x>9?
        movi r2, 0x30
L1:     add r2, r2, r4  
        ret  

【讨论】:

【参考方案2】:

当您屏蔽低四位时,您有可能最终得到 0x0 到 0xF 的值。期望结果表是:

0x0 -> '0' = 0x30
0x1 -> '1' = 0x31
0x2 -> '2' = 0x32
0x3 -> '3' = 0x33
0x4 -> '4' = 0x34
0x5 -> '5' = 0x35
0x6 -> '6' = 0x36
0x7 -> '7' = 0x37
0x8 -> '8' = 0x38
0x9 -> '9' = 0x39
0xA -> 'A' = 0x41
0xB -> 'B' = 0x42
0xC -> 'C' = 0x43
0xD -> 'D' = 0x44
0xE -> 'E' = 0x45
0xF -> 'F' = 0x46

从所需结果表中,我们可以看到有两个线性部分,从 0x0 到 0x9 和从 0xA 到 0xF。对于 0x0 到 0x9 的情况,0x30 - 0x0 = 0x30 所以我们添加 0x30。对于 0xA 到 0xF 部分 0x41 - 0xA = 0x37。

这行得通吗?

0x0 + 0x30 = 0x30
0x1 + 0x30 = 0x31
0x2 + 0x30 = 0x32
0x3 + 0x30 = 0x33
0x4 + 0x30 = 0x34
0x5 + 0x30 = 0x35
0x6 + 0x30 = 0x36
0x7 + 0x30 = 0x37
0x8 + 0x30 = 0x38
0x9 + 0x30 = 0x39

0xA + 0x37 = 0x41
0xB + 0x37 = 0x42
0xC + 0x37 = 0x43
0xD + 0x37 = 0x44
0xE + 0x37 = 0x45
0xF + 0x37 = 0x46

看起来不错。

稍有不同的方法是始终添加 0x30,然后进行调整。

0x0 + 0x30 = 0x30
0x1 + 0x30 = 0x31
0x2 + 0x30 = 0x32
0x3 + 0x30 = 0x33
0x4 + 0x30 = 0x34
0x5 + 0x30 = 0x35
0x6 + 0x30 = 0x36
0x7 + 0x30 = 0x37
0x8 + 0x30 = 0x38
0x9 + 0x30 = 0x39
0xA + 0x30 + 7 = 0x41
0xB + 0x30 + 7 = 0x42
0xC + 0x30 + 7 = 0x43
0xD + 0x30 + 7 = 0x44
0xE + 0x30 + 7 = 0x45
0xF + 0x30 + 7 = 0x46

在创建所需的结果表时,您应该知道左侧与 0xF 相加的内容为您提供 0x0 到 0xF,而且您似乎知道。所需表格的右侧来自 ASCII 图表。我想如果你制作了那个图表并拿出了一个计算器(是的那个带有老年人使用的按钮的小东西,虽然是一个十六进制的,你的手机应该有一个应用程序)。从那里直观地从该表中提出算法。

您还应该问自己,如果我希望 A 到 F 是小写而不是大写 (a,b,c,d,e,f),该怎么办?如何更改算法?

【讨论】:

感谢您的好回答,但我希望了解更多有关汇编编程的信息,因为我仍然怀疑我的程序不正确。我正在用新版本的程序更新问题,请看一下。 好吧,你的代码仍然是错误的,但你更新的算法使用了正确的数字,你在代码中应该有 0x30 的地方有 0x1e,你应该有 0x37 的地方有 0x29。你不需要,最后加上 0xFF,最大的数字是 0xF + 0x37 = 0x46。

以上是关于如何从 4 位十六进制转换为 7 位 ASCII?的主要内容,如果未能解决你的问题,请参考以下文章

ASCII码与BCD码的区别

求帮助,编码转换的问题 python 3.4.0

C语言如何把11位16进制字符串转成16进制数?

浮点数的十六进制表示

16位二进制数怎么转换为BCD码

十进制ASCII码的转换!