Учебник по ассемблеру (ASM)
 

Ассемблер в примерах - Компиляция с 32-разрядными регистрами

Вопрос:
подскажите каким образом можно скомпилировать DOS программу, в которой встречается команда с 32-битным регистром EAX. Мне понятно, что это будет не COM, к которому я привык, а EXE. Я компилирую в основном на MASM611 с помощью команды ml.exe prog.asm /AT, редко на TASM 5.0. Я так предполагаю, что MASM611 не подойдёт для компиляции под DOS, если в программе есть 32-битный регистр, но может TASM тогда подойдёт? И ещё, каким простым и удобным отладчиком воспользоваться, чтобы посмотреть работу откомпилированной программы, в которой есть 32-битный регистр EAX. Я пока пользуюсь только AFDPRO, но он тоже только для 16-битных регистров, как и MASM611.

Ответ:
Размер регистров зависит не от используемой ОС, а от процессора. Под DOS можно писать 32-битные программы, под Windows - 16-битные. Но если вы найдете, например, комп с 286 процессором, то 32-битная программа там не заработает.
Вышесказанное не совсем верно (скажем, для запуска 16-битной программы под VIST'ой требуется оболочка типа DOS Box, а для 286-й можно написать эмулятор Pentium'а), но основная мысль, думаю, понятна: за регистры отвечает собственно процессор, а не ОС.
Далее.
Тип исполняемого файла (COM или EXE для DOS) - это вотчина ОС, а не процессора. Это ОС распределяет память, загружает программу, настраивает регистры и т.д. Процессор про это, грубо говоря, вообще не в курсе. А ОС абсолютно по барабану, что именно записано в файле. Ей главное (в случае с EXE, с COM не нужно даже этого), чтобы заголовок программы был корректным. В случае EXE-файла ОС считывает заголовок, загружает в свободное место код программы, настраивает адреса (в соответствии с таблицей настроек в заголовке), а также стек и передает управление по адресу, указанному в заголовке.
В случае с COM все вообще просто: резервируется вся свободная память, формируется префикс программы (256 байт, т.н. область PSP), файл загружается в память непосредственно за этой областью и производится передача управления по адресу PSP:100h, где PSP - сегментный адрес области PSP.
Для чего я это так подробно расписал. А для того, чтобы показать, что ОС не в курсе, что именно у вас написано в программе. Программа выполняется процессором, а не ОС.
TASM, MASM, а также остальные компиляторы ассемблера позволяют формировать 32-хразрядные команды.
Для этого нужно вначале программы указать директиву .386 (как минимум).
После этого можно использовать все регистры (например, AL, AX, EAX).
Замечу, что при трансляции исходного текста 32-разрядные команды будут преобразованы в код при помощи префикса изменения размерности операнда. Проще говоря, непосредственно команды для 16-ти и 32-битовых регистров одинаковы. Они отличаются только префиксом.
Соответственно, вы можете формировать 32-разрядные команды и вручную, написав:

db 66h
mov ax, si

Такая запись эквивалентна следующей:

mov eax, esi

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

db 66h
mov ax, 1
nop ; код 90h
nop ; код 90h

эквивалентна не такому фрагменту:

mov eax, 1
nop
nop

а такому:

mov eax, 90900001h

Для достижения нужного результата надо писать так:

db 66h
mov ax, 1
db 0, 0

Резюмируя, и TASM, и MASM при указании директивы .386 способны формировать 32-разрядный код, причем он может быть использован как при создании COM, так и при создании EXE файлов.
В качестве отладчика для DOS рекомендую Turbo Debugger от Borland. td32 позволяет просматривать 32-битные регистры. Только после запуска нужно специально это указать.


   Вперёд
   Содержание