RodionGork's blog

By RodionGork, 13 years ago, In Russian

В посте об уличной магии коллега затронул тему, которая быть может не всем близка, не всем понятна и т.п.

Не могу ответственно сказать, очень ли важны эти тайные знания, но думаю не будет беды, если попробую показать пару фокусов, благодаря которым эта "магия" может быть доступна каждому.

Напишем программу "Хелло Ворлд", такого размера, что выводимый текст будет занимать в ней больше половины!

Как и вся магия, она будет плохо переносима, но под дос и винды работать будет. Что нам понадобится? Утилита debug.exe - в современных виндах она живёт в c:\windows\system32 - это примитивный дебаггер который остался там рудиментарно с самых старинных версий доса... Кое для чего он ещё может пригодиться! (хотя для серьёзной разработки на ассемблере нужен нормальный компилятор - ну а простенькие вещи и в дебаггере можно накидать)

Если вы работаете из под linux, как я, то вам понадобится либо виртуальная машина, либо dosbox.

Итак, запустите окошко с командной строкой (например, cmd) и выполните команду:

С:\>debug.exe

Здесь и далее договоримся что полужирным отмечено то, что пишем мы, а простым - то что нам отвечает система.

Вы должны увидеть приглашение в виде единичного тире (минуса, дефиса) в левой позиции экрана. Введите команду "a" и нажмите enter. Слева появится шестнадцатеричный адрес в виде сегмент:смещение. Сегмент может оказаться довольно произвольным, а смещение будет 100 - с этого адреса грузятся в память программы в формате COM. Вводите дальше инструкции, строка за строкой (всего 4)

-a
7234:0100 mov ah,9
7234:0102 mov dx,109
7234:0105 int 21
7234:0107 int 20
7234:0109

В пятой строке вы просто нажмёте enter и опять перейдете в режим приглашения.

Наша программа состоит из 4 команд - из них первые три посвящены вызову системной функции печати строки. Первая загружает номер подфункции (9) в регистр процессора ah, вторая загружает адрес выводимой строки (её смещение) в регистр dx а третья вызывает системную функцию (прерывание) номер 21h - это прерывание зарезервировано за большим количеством простейших полезных функций операционной системы ДОС. В частности 9-я подфункция печатает строку с заданного в dx адреса до символа доллар.
В четвёртой строке мы вызываем ещё одну системную функцию, номер 20h (она не требует каких-либо аргументов в регистрах процессора) - выход из программы (да, в таких маленьких программах выходом нужно заниматься специально!)

Но ведь у нас ещё не записана выводимая строка? Нет проблем. Правда debug.exe не умеет задавать текст, но будем действовать так: введите команду e 109 (ввод данных побайтово с такого то адреса) и потом набирайте, нажимая пробел после каждых двух символов (оно само будет переходить к следующему байту) шестнадцатеричные значения. Старые значения байтов будут отображаться перед точкой, новые после:

-e 109
7234:0109   45.48   24.65   55.6C   47.6C   00.6F   00.0D   00.0A
7234:0110   50.24

Введя последнее значение, мы опять нажали enter. Введите d 109 (дамп памяти с заданного адреса) и убедитесь что всё верно (там справа будет отображаться текстовое представление, что удобно). Вообще нужно понимать, что эту цепочку байтов я не высасывал из пальца, а просто набрал в блокноте а потом сохранённый файл дампировал тем же debug.exe

Теперь дело за малым - укажем размер файла, его имя - и сохраним его

-r cx
CX 0000
:11
-n hw.com
-w
Writing 00011 bytes

Здесь нужно пояснить только две вещи - размер программы - от адреса 100 до адреса 110 включительно - 17 байт (11h) - это число надо записать в регистр CX (но не в режиме работы программы, а в самом отладчике, т.е. как бы в текущее состояние процессора).
Имя файла должно иметь расширение COM - это самый старый формат исполнимых файлов в DOS, он не требует специальных таблиц загрузки как EXE (хотя там есть смешной нюанс, в который не будем углубляться - формат определяется не по расширению а по сигнатуре MZ в начале).

Теперь вводите команду "q" чтобы выйти из дебаггера обратно в командную строку.

Выполните созданную программу:
C:\>hw.com
Hello
C:\>

Проверьте её размер:

C:\>dir hw.com
HW          COM        17 ....
1 file    17 bytes

95% из читающих это, это знание никогда не понадобится. Но в качестве развлечения - тем кто не знает что такое ассемблер, процессор и его регистры, адреса памяти, функции операционной системы и т.п. - всё это может сгодиться, не так ли? В инете вы можете найти массу информации на эту тему - ну или спросить меня если что. ;-)

Добавлю, что до недавнего времени проводились соревнования Hugi Compo - кто напишет самую маленькую программу выполняющую требуемые действия (например, распечатывающую текущий каталог).

Актуальность ассемблера для x86 сейчас сильно снижается по понятным причинам, хотя ессно существует куча других процессоров, систем и ассемблеров. Если будете программировать стиральные машины или микроволновки - обязательно об этом узнаете. ;-)

  • Vote: I like it
  • +46
  • Vote: I do not like it