Как и все данные, символы в памяти компьютера представляют набор битов - единиц и нулей, упорядоченных определенным образом. Большинство компьютеров для представления одного символа используют 1 или 2 байта. Windows, macOS, FreeBSD и Linux используют для символов кодировку ASCII или Unicode.
Таблица ASCII (American Standard Code for Information Interchange) представляет один из наиболее простых и популярных способов кодирования символов. ASCII представляет таблицу кодировки символов, в которой каждому символу соответствует определенное число. Например, латинской букве A соответствует число 65, а букве B - число 66. Более того цифровые символы имеет свои собственные числовые коды. Например, символу 0 соответствует число 48, символу 1 - число 49 и т.д. Каждый отдельный символ из таблицы ASCII представляет 1 байт.
Первые 31 символов - управляющие последовательности.
DEC | HEX | BIN | Символ | Описание |
0 | 00 | 00000000 | NUL | Ноль/нулевой байт |
1 | 01 | 00000001 | SOH | Начало заголовка |
2 | 02 | 00000010 | STX | Начало текста |
3 | 03 | 00000011 | ETX | Конец текста |
4 | 04 | 00000100 | EOT | Конец передачи |
5 | 05 | 00000101 | ENQ | запрос |
6 | 06 | 00000110 | ACK | Подтверждение |
7 | 07 | 00000111 | BEL | Сигнал/звонок |
8 | 08 | 00001000 | BS | Шаг назад |
9 | 09 | 00001001 | HT | Горизонтальная табуляция |
10 | 0A | 00001010 | LF | Перевод строки |
11 | 0B | 00001011 | VT | Вертикальная табуляция |
12 | 0C | 00001100 | FF | Новая страница |
13 | 0D | 00001101 | CR | Возврат каретки |
14 | 0E | 00001110 | SO | Выключить сдвиг |
15 | 0F | 00001111 | SI | Включить сдвиг |
16 | 10 | 00010000 | DLE | Ключ связи данных |
17 | 11 | 00010001 | DC1 | Управиление устройством 1 |
18 | 12 | 00010010 | DC2 | Управиление устройством 2 |
19 | 13 | 00010011 | DC3 | Управиление устройством 3 |
20 | 14 | 00010100 | DC4 | Управиление устройством 4 |
21 | 15 | 00010101 | NAK | Отрицательное подтверждение |
22 | 16 | 00010110 | SYN | Синхронизация |
23 | 17 | 00010111 | ETB | Конец передаваемого блока |
24 | 18 | 00011000 | CAN | Отмена |
25 | 19 | 00011001 | EM | Конец среды |
26 | 1A | 00011010 | SUB | Замена |
27 | 1B | 00011011 | ESC | Выход |
28 | 1C | 00011100 | FS | Разделитель файлов |
29 | 1D | 00011101 | GS | Разделитель групп |
30 | 1E | 00011110 | RS | Разделитель записей |
31 | 1F | 00011111 | US | Разделитель модулей |
Печатные символы
DEC | HEX | BIN | Символ |
32 | 20 | 00100000 | пробел |
33 | 21 | 00100001 | ! |
34 | 22 | 00100010 | " |
35 | 23 | 00100011 | # |
36 | 24 | 00100100 | $ |
37 | 25 | 00100101 | % |
38 | 26 | 00100110 | & |
39 | 27 | 00100111 | ' |
40 | 28 | 00101000 | ( |
41 | 29 | 00101001 | ) |
42 | 2A | 00101010 | * |
43 | 2B | 00101011 | + |
44 | 2C | 00101100 | , |
45 | 2D | 00101101 | - |
46 | 2E | 00101110 | . |
47 | 2F | 00101111 | / |
48 | 30 | 00110000 | 0 |
49 | 31 | 00110001 | 1 |
50 | 32 | 00110010 | 2 |
51 | 33 | 00110011 | 3 |
52 | 34 | 00110100 | 4 |
53 | 35 | 00110101 | 5 |
54 | 36 | 00110110 | 6 |
55 | 37 | 00110111 | 7 |
56 | 38 | 00111000 | 8 |
57 | 39 | 00111001 | 9 |
58 | 3A | 00111010 | : |
59 | 3B | 00111011 | ; |
60 | 3C | 00111100 | < |
61 | 3D | 00111101 | = |
62 | 3E | 00111110 | > |
63 | 3F | 00111111 | ? |
64 | 40 | 01000000 | @ |
65 | 41 | 01000001 | A |
66 | 42 | 01000010 | B |
67 | 43 | 01000011 | C |
68 | 44 | 01000100 | D |
69 | 45 | 01000101 | E |
70 | 46 | 01000110 | F |
71 | 47 | 01000111 | G |
72 | 48 | 01001000 | H |
73 | 49 | 01001001 | I |
74 | 4A | 01001010 | J |
75 | 4B | 01001011 | K |
76 | 4C | 01001100 | L |
77 | 4D | 01001101 | M |
78 | 4E | 01001110 | N |
79 | 4F | 01001111 | O |
80 | 50 | 01010000 | P |
81 | 51 | 01010001 | Q |
82 | 52 | 01010010 | R |
83 | 53 | 01010011 | S |
84 | 54 | 01010100 | T |
85 | 55 | 01010101 | U |
86 | 56 | 01010110 | V |
87 | 57 | 01010111 | W |
88 | 58 | 01011000 | X |
89 | 59 | 01011001 | Y |
90 | 5A | 01011010 | Z |
91 | 5B | 01011011 | [ |
92 | 5C | 01011100 | \ |
93 | 5D | 01011101 | ] |
94 | 5E | 01011110 | ^ |
95 | 5F | 01011111 | _ |
96 | 60 | 01100000 | ` |
97 | 61 | 01100001 | a |
98 | 62 | 01100010 | b |
99 | 63 | 01100011 | c |
100 | 64 | 01100100 | d |
101 | 65 | 01100101 | e |
102 | 66 | 01100110 | f |
103 | 67 | 01100111 | g |
104 | 68 | 01101000 | h |
105 | 69 | 01101001 | i |
106 | 6A | 01101010 | j |
107 | 6B | 01101011 | k |
108 | 6C | 01101100 | l |
109 | 6D | 01101101 | m |
110 | 6E | 01101110 | n |
111 | 6F | 01101111 | o |
112 | 70 | 01110000 | p |
113 | 71 | 01110001 | q |
114 | 72 | 01110010 | r |
115 | 73 | 01110011 | s |
116 | 74 | 01110100 | t |
117 | 75 | 01110101 | u |
118 | 76 | 01110110 | v |
119 | 77 | 01110111 | w |
120 | 78 | 01111000 | x |
121 | 79 | 01111001 | y |
122 | 7A | 01111010 | z |
123 | 7B | 01111011 | { |
124 | 7C | 01111100 | | |
125 | 7D | 01111101 | } |
126 | 7E | 01111110 | ~ |
127 | 7F | 01111111 | DEL |
Для определения символа или строки в ассемблере применяются кавычки. Можно использовать как одинарные кавычки, так и двойные:
.code main proc mov rax, "A" ; в регистре RAX числовой код символа A - 65 mov r8, 'B' ; в регистре R8 числовой код символа B - 66 ret main endp end
Для определения переменных, которые представляют символы ASCII, применяется тип byte
:
.data char byte "D" ; определяем один символ .code main proc mov al, char ; в регистре AL числовой код символа D - 68 ret main endp end
Если мы посмотрим на таблицу ASCII, то увидим, что данная кодировка упрощает в некоторых случаях манипуляции с данными. Так, строчные буквы отличаются от заглавным установленным 6-м битом:
Буква A 01000001 Буква a 01100001
Соответственно, чтобы, например, перевести строчную букву в верхний регистр, достаточно снять шестой бит, а чтобы сделать заглавную букву строчной - наоборот, установить шестой бит. Для установки этого бита можно прибавить к числовому коду символа число 32, а для сброса этого бита - отнять от числового кода символа 32.
Или например, из таблицы мы видим, что числовой код цифровых символов начинается с 48 (или с 30 в 16-й сиситеме). Поэтому для перехода от числа к его символьному представлению и обратно мы можем прибавлять/вычитать 48.
Поскольку бинарный код чисел отличается от бинарного кода цифровых символов только старшим полубайтом, который у символов равен 3, то для перехода от символа к числу можно применить операцию AND, которая сбросит полубайт. А для перехода от числа к его символьному представлению можно установить полубайт с помощью операции OR. Например, преобразуем символ в число:
.code main proc mov rax, "2" ; числовой код цифры 2 равен 50 или 00110010 and rax, 0Fh ; убираем старший полубайт - 0011 с помощью маски 00001111 ret main endp end
Здесь преобразуем в число символ 2. В бинарной форме он равен 00110010. То есть нам надо сбросить первый полубайт 0011. Для этого применяем логическое умножение на число 0Fh, что в двоичной форме равно 00001111. То есть получим:
00110010 * 00001111 = 00000010
То есть получаем бинарное представление числа 2. Причем 0Fh - это маска, которая подходит для перехода от любого цифрового символа к числу для все числовых значений. Выполним обратный переход:
.code main proc mov rax, 2 ; числовой код 2 равен 00000010 or rax, 30h ; устанавливаем старший полубайт в 0011 с помощью маски 0011000 ret main endp end
Здесь преобразуем число 2 в соответствующий символ. В бинарной форме число 2 равно 00000010. То есть нам надо установить старший полубайт в 0011. Для этого применяем логическое сложение с числом 30h, что в двоичной форме равно 00110000. То есть получим:
00000010 + 00110000 = 00110010
То есть получаем число 50 - числовой код символа "2".
Подобным образом используя логического сложение с маской 20h можно получить из заглавной буквы строчную:
.code main proc mov rax, "A" ; числовой код символа A равен 65 или 01000001 or rax, 20h ; 01000001 + 00100000 = 97 - код символа a ret main endp end
Используя логическое умножение на маску DFh или 11011111, можно перейти от строчной к заглавной букве:
.code main proc mov rax, "a" ; числовой код символа a равен 97 или 01100001 and rax, 0DFh ; 01100001 * 11011111 = 01000001 = 65 - код символа A ret main endp end
Для той же цели можно прибавлять/вычитать 32 из кода символа:
.code main proc mov rax, "A" ; в RAX код 65 add rax, 32 ; 65 + 32 = 97 - код символа a ret main endp end