Как преобразовать 4-битный шестнадцатеричный в 7-битный ASCII?

Задача состоит в том, чтобы изучить программирование на ассемблере, написав подпрограмму, которая может преобразовывать 4-битный шестнадцатеричный код в 7-битный ASCII. Сначала я понятия не имел, но после некоторых исследований я мог приложить усилия и нарисовать блок-схему и составить программу, но это не совсем правильно, поэтому я прошу вашего руководства, чтобы помочь мне решить эту проблему.

Собственно текст задания такой:

ГА 3.1. Нарисуйте блок-схему подпрограммы для преобразования 4-битного шестнадцатеричного значения в соответствующий 7-битный код ASCII. См. полную спецификацию для hexasc ниже. Пример: двоичное число 0010 (шестнадцатеричная цифра 2) преобразуется в 011 0010 (ASCII-код для «2»). Другой пример: двоичное число 1011 (шестнадцатеричная цифра B) преобразуется в 100 0010 (ASCII-код для 'B'). Убедитесь, что ваша подпрограмма задокументирована в соответствии с нашими требованиями.

ГА 3.2. Используя лабораторный проект в Nios II IDE, создайте новый файл с именем hexasc.s.

ГА 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

person Niklas R.    schedule 21.08.2012    source источник
comment
Схема неверна в цифрах. ASCII(x) = x + 30H(48d), если 0‹=x‹=9, или x + 37H(55d) в противном случае (10‹=x‹=15).   -  person Alexey Frunze    schedule 21.08.2012
comment
@AlexeyFrunze Спасибо за комментарий. Я могу скорректировать диаграмму так, чтобы она была правильной, но мне может понадобиться ясность в отношении алгоритма. В нем говорится, что один алгоритм преобразования между шестнадцатеричным и ASCII - это a=h+((h>9)?55:49);, но я не уверен, что понимаю.   -  person Niklas R.    schedule 21.08.2012
comment
Я почти уверен, что вы должны маскировать и сохранять только последние четыре бита, а не байты. Ваш код делает это правильно.   -  person harold    schedule 21.08.2012
comment
Что непонятно в a=h+((h>9)?55:49)? Это то, что теперь описывает исправленная диаграмма, за исключением того, что в формуле должно быть 48, а не 49.   -  person Alexey Frunze    schedule 21.08.2012
comment
Я не знаю, какой ассемблер вы используете, но он наверняка может работать с символьными литералами, а не только с числами. Чтобы преобразовать 5 в ASCII, вы просто добавляете 5 к символу '0'. Пусть ассемблер выполнит работу по оценке того, что '0' равно 30H, а 30H + 5 равно 35H, что является символом ASCII «5». Если вы сделаете это таким образом, ваш код будет самодокументируемым, а не замусоренным магическими числами.   -  person indiv    schedule 21.08.2012
comment
@indiv Спасибо, наконец, я думаю, что понимаю, что происходит. Мне просто нужно исправить маленькую программу, я думаю, что это не так, как сейчас.   -  person Niklas R.    schedule 21.08.2012
comment
Из множества вопросов о том, как преобразовать десятичные, двоичные, шестнадцатеричные, ascii-вопросы, которые мы видели в SO. На этот стоит ответить, потому что вы действительно пытались это сделать, продумали это, поняли системы счисления и представления битов, просто допустили тонкую математическую ошибку.   -  person old_timer    schedule 21.08.2012


Ответы (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)? Как изменить алгоритм?

person old_timer    schedule 21.08.2012
comment
Спасибо за хороший ответ, но мне бы хотелось узнать больше о программировании на ассемблере, так как я все еще подозреваю, что моя программа неверна. Я обновляю вопрос новой версией программы, пожалуйста, посмотрите. - person Niklas R.; 22.08.2012
comment
хорошо, код, который у вас есть, все еще неверен, но ваш обновленный алгоритм использует правильные числа, у вас есть 0x1e в коде, где у вас должно быть 0x30, и 0x29, где у вас должно быть 0x37. вам это не нужно, и с 0xFF в конце самые большие числа будут 0xF + ​​0x37 = 0x46. - person old_timer; 22.08.2012

Некоторые ошибки в блок-схеме

1. Маскируйте и сохраняйте только последние четыре байта --> биты
2.Решение 0<x<9 --> 0<=x<=9
3.Решение 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  
person Sep Roland    schedule 28.12.2014