Сборка, смена символов AF на десятичное число

У меня проблема с моим ассемблерным кодом. Я хочу преобразовать символ ввода пользователя между AF в их соответствующее десятичное число.

Образец вывода:

Введите символ из AF: B В десятичном виде это 11.

Я не могу справиться с конверсией. Пожалуйста, помогите мне. Спасибо Это код

.model small
.stack 100h
.data
        msg1 db 'Enter a character from A_F:$ '
        msg2 db 'In decimal it is:$'
        char db ?
.code
MAIN PROC
        mov ax,@data
        mov ds,ax

        mov ah,09h                ;Displaying msg1
        mov dx,offset msg1
        int 21h
        mov ah,01h                ;Taking input
        int 21h
        mov char,al

        mov ah,2                    ;For go to next line
        mov dl,0dh
        int 21h
        mov dl,0ah
        int 21h                        ;Displaying msg2
        mov ah,09h
        mov dx,offset msg2
        int 21h                
        mov ah,02h          ;converting character   
        sub char,30h
        mov dl,char
        int 21h

        mov ah,4ch
        int 21h
MAIN ENDP
END MAIN

1 ответ

Так что вы можете обманывать и просто иметь справочную таблицу (есть еще более простой чит). Но правильный путь - просто сделать математику. Вы должны преобразовать из базы 2 или технически базы 16 в базу 10. Вы можете легко перемещаться из базы 2 в базу 8 (восьмеричное) в базу 16 (шестнадцатеричное) с помощью всего лишь битовой манипуляции, потому что 8 и 16 - степени 2. Но 10 не является степенью 2, вы не можете сделать это с помощью битовых манипуляций.

Одна из них, с которой мы более знакомы, это временная база 60 для часов, минут, секунд. 1 час - 60 минут, одна минута - 60 секунд, так сколько часов - 4321 секунда? как ты это решаешь? сколько секунд в часе? 60 * 60 = 3600 верно? два часа - это 7200 секунд, поэтому 4321 находится где-то между единицами и, а именно, 4321/3600 или 1 остаток 721 или 1 час 721 секунда. сколько минут в 721 секунде? 721/60 = 12 остаток 1, поэтому 4321 секунда - 1 час 12 минут 1 секунда. только для проверки 3600 * 1 + 12 * 60 + 1 = 4321. или (60 ^ 2) * 1 + (60 ^ 1) * 12 + (60 ^ 0) * 1 - 4321.

Как насчет 0x1234 до десятичного? наш калькулятор сообщает нам 4660. Короткий ответ: уменьшите число степеней, равных или превышающих число 10. поэтому 16-битное число не может быть больше 65535, поэтому 10000-е место или 10 ^ 4. 0x1234 / 10000 = 0 остаток 0x1234. возьмите остаток 0x1234 / 1000 = 4 остатка 0x294 (660), возьмите остаток 0x294 / 100 = 6 остатка 0x3C (60), возьмите остаток 0x3C / 10 = 6 остаток 0, возьмите остаток 0 / 1 = 0. захватите все частное 04660, так что ответ 4660 десятичных.

Таким образом, буква B - это число ASCII 0x42, нижний регистр 0x62, поэтому вы должны быть осторожны там. 0x42 - 0xB = 0x37.

Таким образом, вычитая 0x30 из символов ascii 0-9, вы получите число 0 - 9. Но если вы знаете / предполагаете, что это (шестнадцатеричное) число и оно больше 0x39, то вместо этого вычтите 0x37. 0x42 - 0x37 = 0xB, 0x62 - 0x37 = 0x2B, вы можете и с 0xF и очистить это для верхнего и нижнего регистра.

4 бита, наибольшее число - 15, поэтому для преобразования из базы 2/16 в базу 10 нам нужно иметь дело только с 10^1 и 10^0. поэтому 0xB / 10 = 1 остаток 1 1/1 = 1, возьмите значения 0xB = 11 десятичные.

простейший читер здесь, если ваши входные данные ограничены между 0xA и 0xF, то есть от 10 до 15. Вы знаете, что все числа, разделенные на 10, представляют собой 1 остаток от 0 до 5., так что просто вычтите из 10, и вы получите от 0 до 5.

Следующая проблема: вы берете 0x42 (символ B) и вычитаете 0x30, то есть 0x12, управляющий устройством на диаграмме ascii, в принципе нет смысла пытаться использовать int21 ah = 2 с этим символом. чтобы распечатать число 11, вы должны напечатать 0x31, а затем еще 0x31. если ваш ввод был F, ответ 15, вы отправляете 0x31 и 0x35. чит должен принять 0x46 от вашего ввода ('F'), вычесть 0x37, чтобы получить 0xF, затем вычесть 10, чтобы получить 0x5, вывести 0x31 для 10, затем добавить 0x30 к 0x5, чтобы получить 0x35, и вывести его. Вы можете объединить вычитание 0x37 и 10 в 0x41.

'A' = 0x41,  0x41 - 0x41 = 0x00, 0x00+0x30 = 0x30 = '0'
'B' = 0x42,  0x42 - 0x41 = 0x01, 0x01+0x30 = 0x31 = '1'
'C' = 0x43,  0x43 - 0x41 = 0x02, 0x02+0x30 = 0x32 = '2'
'D' = 0x44,  0x44 - 0x41 = 0x03, 0x03+0x30 = 0x33 = '3'
'E' = 0x45,  0x45 - 0x41 = 0x04, 0x04+0x30 = 0x34 = '4'
'F' = 0x46,  0x46 - 0x41 = 0x05, 0x05+0x30 = 0x35 = '5'

или даже более оптимизированы для ваших конкретных пределов ввода

'A' = 0x41, 0x41 - 0x11 = 0x30 = '0'
'B' = 0x42, 0x42 - 0x11 = 0x31 = '1'
'C' = 0x43, 0x43 - 0x11 = 0x32 = '2'
'D' = 0x44, 0x44 - 0x11 = 0x33 = '3'
'E' = 0x45, 0x45 - 0x11 = 0x34 = '4'
'F' = 0x46, 0x46 - 0x11 = 0x35 = '5'

Вы можете пойти так далеко, чтобы ограничить проверку, и если входной символ меньше 0x41 или больше 0x46, возможно, выведите '?' (0x3F) вместо числового ответа.

Таким образом, ваше преобразование неверно в двух отношениях: во-первых, вы забыли, что для вывода чисел от 10 до 15 требуется два символа. Во-вторых, результатом вашей математики должен быть символ, который имеет смысл (между 0x30 и 0x35)

Другие вопросы по тегам