
Данные в ассемблере.
Данные в ассемблере — понятие широкое. Программу в целом можно воспринимать как одну большую совокупность данных, однако мы уже знаем и помним, что она состоит из данных и кода — набора команд, необходимых для обработки данных.
Данные в ассемблере в узком понимании (буква, строка, символ, текстовый файл, звуковой файл, видеофайл, документ Word и т.п), а также сам код представляют собой определённую строго регламентированную последовательность чисел. Эта последовательность формируется при преобразовании программного текста в исполняемый файл, то есть написанный программистом код транслируется в машинный язык цифр.
Машина манипулирует минимальным блоком памяти размером в 1 байт. Байт состоит из 8 бит и может содержать 256 значений (2 в степени 8). Байтовый мир машин транслируется отладчиками, дизассемблерами и HEX-редакторами в 16-тиричном виде для более удобного восприятия человеком.
Для дальнейшего изучения вопроса нам понадобиться редактор HIEW. Он есть среди прочего необходимого в архиве DOS-1.rar, который необходимо скачать.
Байты, слова, двойные слова …
Фактически все программы — от простых до самых сложным представляют собой набор команд процессора, манипулирующих с данными.
Команды процессора представляют собой цифровые значения, имеющие свою структуру.
Открываем с помощью Hiew нашу программу PRG.COM (выбор файлов — F9). При помощи F4 выбираем режим отображения информации HEX (как вы уже знаете, шестнадцатиричный режим):
1 2 |
00000000: B4 09 BA 08-01 CD 21 C3-48 65 6C 6C-6F 20 57 6F + ¦ =!+Hello Wo 00000010: 72 6C 64 21-0D 0A 24 - - rld! $ |
Мы видим набор байт: B4 09 BA 08 01 CD 21 и т.д. Байты разделены дефисами на группы — по четыре в каждой.
Группы байт имеют названия:
- Группа из 2 байт называется Word («Слово»).
- Группа из 4 байт называется Double Word («Двойное слово»).
- Группа из 8 байт называется Quatro Bytes («Восемь байт»).
- Группа из 10 байт называется Tetro Bytes («Десять байт»).
В ассемблере имеются специальные директивы для резервирования памяти:
- DB — Define Bite.
- DW — Define Word.
- DD — Define Double Word.
- DQ — Define Quatro Bites
- DT — Define Tetro Bites.
Код и данные — это упорядоченная последовательность чисел.
Одну из этих директив мы использовали в нашем коде для резервирования памяти и заполнения её текстом:
1 |
message db "Hello World!",0Dh,0Ah,'$' ; строка для вывода |
Переходим в режим декодирования (F4->Decode):
1 2 3 4 5 6 7 8 9 10 11 12 13 |
00000000: B409 mov ah,009 ;" " 00000002: BA0801 mov dx,00108 ;" " 00000005: CD21 int 021 00000007: C3 retn 00000008: 48 dec ax 00000009: 65 gs: 0000000A: 6C insb 0000000B: 6C insb 0000000C: 6F outsw 0000000D: 20576F and [bx][0006F],dl 00000010: 726C jb 00000007E 00000012: 64210D and fs:[di],cx 00000015: 0A24 or ah,[si] |
Для машины и код и данные — это строго упорядоченная последовательность цифр. Мы видим, что дизассемблер попытался перевести в код и нашу строку «Hello World!»,0Dh,0Ah,’$’, но мы можем различить её по набору байт от 48h до 24h.
Ассемблерный код также представлен в виде цифр. Шестнадцатеричное число B409 декодируется в инструкцию mov ah,009. При этом, очевидно, что B4 — это «mov ah», а 09 — это число «09» (ещё один ноль добавлен HIEW перед числом, чтобы показать его принадлежность именно к числовому значению и мы его не будем учитывать).
Во второй строке кода обратите внимание на последовательность байт: BA 08 01, которая декодируется в инструкцию:
1 |
00000002: BA0801 mov dx,00108 |
Понятно, что BA — это «mov dx», а 0801 — это число «0108 » (первый ноль добавил HIEW). Однако отображена оно в коде побайтно наоборот — зеркально.
Младший байт — меньший адрес.
Продолжаем изучать данные в ассемблере и переходим к очень важному моменту, который необходимо запомнить: Младший байт числа в памяти компьютера имеет меньший адрес, поэтому читается «попарно и задом на перёд». В дизассемблированном коде (как часть ассемблерной команды, либо в как часть стека) число будет выглядеть «обычно».
Ещё раз:
1 |
mov dx,00108; |
команда ассемблера обозначает: «поместить в регистр dx шестнадцатеричное число 108 (0108h). Число 108 побайтно выглядит как слово 01 08. 08 — это младший байт, 01 — старший. Слово 01 08 расположено в памяти по адресам 00000003: и 00000004:, значит 08 должно находится по младшему адресу — 00000003:, а 01 — по старшему — 00000004, как оно и есть.
Итак, 16-ти битное число 1234h в памяти будет храниться как последовательность байт 34 12. Windows программирование оперирует с 32 и 64 битными числами: 32 битное число 12345678h будет храниться как последовательность байт 78 56 34 12, а 64 битное число 123456789ABCDEF0h будет храниться как
последовательность байт F0 DE BC 9A 78 56 34 12.