Search code examples
assemblyhexmipsnios

How to convert from 4-bit hexadecimal to 7-bit ASCII?


The assigment is to learn assembly programming by writing a subroutine that can convert between 4-bit hexadecimal and 7-bit ASCII. At first I had no idea but after some research I could make and effort and draw a flowchart and make a program but it is not entirely correct so I'm asking for your guidance to help me solve this.

The actual assignment text is this:

HA 3.1. Draw a flow-chart for a subroutine to convert a 4-bit hexadecimal value to the corresponding 7-bit ASCII-code. See the full specification for hexasc below. Example: binary 0010 (hexadecimal digit 2) is converted to 011 0010 (ASCII-code for '2'). Another example: binary 1011 (hexadecimal digit B) is converted to 100 0010 (ASCII-code for 'B') Make sure that your subroutine is documented according to our requirements.

HA 3.2. Using the labwork project in the Nios II IDE, create a new file called hexasc.s

HA 3.3. In the file hexasc.s, write a subroutine called hexasc, that converts a 4-bit hexadecimal value to the corresponding 7-bit ASCII-code.

I've drawn a flowchart for the program: enter image description here

And the program I've tried is this but I suspect that it is not according to spec:

        .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 

Can you help me develop and solve this assignment? There's plenty of time, it's not due until in a month.

Update

After seeing here in a comment that the flowchart was incorrect, I've made the necessary adjustments: enter image description here

I also want to discuss how this algorithm is correct that converts between hexadecimal and ASCII.

Update / edit

Here is the complete program.

.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

Solution

  • When you mask off the lower four bits, you have the potential for ending up with the values 0x0 to 0xF. The table of desired results is:

    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
    

    From that table of desired results we can see that there are two linear sections, from 0x0 to 0x9 and from 0xA to 0xF. For the 0x0 to 0x9 case 0x30 - 0x0 = 0x30 so we add 0x30. For the 0xA to 0xF section 0x41 - 0xA = 0x37.

    Will that work?

    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
    

    Looks good.

    A slightly different way is always add 0x30 then adjust after.

    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
    

    When creating the desired result table, the left side you should have known something anded with 0xF gives you 0x0 to 0xF, and it appears you did. The right side of the desired table comes from an ASCII chart. I think if you had made that chart and gotten out a calculator (yea that little thing with buttons that old people use, although one that does hex, your phone should have an app for it). From there visually from that table come up with the algorithm.

    You should also ask yourself, what if I want A to F to be lower case instead of upper case (a,b,c,d,e,f)? How do I change the algorithm?