В посте об уличной магии коллега затронул тему, которая быть может не всем близка, не всем понятна и т.п.
Не могу ответственно сказать, очень ли важны эти тайные знания, но думаю не будет беды, если попробую показать пару фокусов, благодаря которым эта "магия" может быть доступна каждому.
Напишем программу "Хелло Ворлд", такого размера, что выводимый текст будет занимать в ней больше половины!
Как и вся магия, она будет плохо переносима, но под дос и винды работать будет. Что нам понадобится? Утилита 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 сейчас сильно снижается по понятным причинам, хотя ессно существует куча других процессоров, систем и ассемблеров. Если будете программировать стиральные машины или микроволновки - обязательно об этом узнаете. ;-)
Это совершенно непринципиально. По работе я вообще с ассемблерами для PC не сталкивался. Ну а для контроллеров у которых до 64кб ROM и пара килобайт оперативки сами понимаете, сегментация редко встречается... ;-)
В данном случае дебаггер работает в реальном режиме, поэтому и хрен с ним %)
UPD: да и в 32-битном режиме (в защищённом) вы ведь тоже можете иметь целую кучу сегментов пересекающихся/нахлёстывающихся как угодно... Только что они в принципе побольше могут быть... Ну да, надо говорить "селектор/дескриптор", но какая разница... ;-)
По-настоящему крутой в этом отношении всё-таки компилятор от GNU - микрософт там и рядом не стоял - но пока разберёшься с его форматами вставок - есть шанс голову сломать... ;-)
Представьте например что у вас строка - литерал. Она хранится в памяти кода. Но при работе она должна находиться в ОЗУ - т.е. при инициализации её надо туда скопировать, да ещё место зарезервировать. Это просто жуть.
Про дифференциальный счётчик для линейного шагового двигателя
Или хотя бы о простом радиофотоплетизмографе:
Умница!