Сперва медитативная часть. Вспоминаем, что один и тот же физический байт памяти может иметь различные логические адреса, определяемые разными, но при этом эквивалентными парами сегмент-смещение. Скриншот для медитации:

Далее практическая часть.
Справедливости ради, оттранслируем hello.asm при помощи MASM с ключами генерации листинга и карты. Запускаем m.bat и даем команду ml /Fl /Fm hello.asm. Замечаем что для MASM надо указывать расширение – .asm. В результате работы ассемблера получаем четыре файла: hello.obj, hello.lst, hello.map и hello.exe.


Теперь начнем эксперименты с выравниваниями сегментов. Изменим немного программу hello.asm добавив атрибут выравнивания byte к командам описаниям сегментов. Cохраним текст программы, как hello1.asm, ассемблируем с генерацией листинга, и посмотрим, что получилось.





Теперь опять медитация. Будем созерцать под отладчиком обе программы: hello.exe и hello1.exe.

Как видно из дампов памяти отладчиков, в программе hello.exe присутствуют пустые промежутки (отмечены зеленым), в программе hello1.exe их нет, так как использовался атрибут выравнивания byte в директивах segment. В результате этого произошло смещение сегмента данных, что отразилось на команде mov dx,offset msg, которая в программе hello.exe имеет вид mov dx,0000, а в программе hello1.exe – mov dx,0001.
Еще один интересный момент это то, что команда mov ax,data в обеих программах имеет одинаковый машинный код mov ax,144D, не смотря на то, что в программе hello1.exe мы применили выравнивание параграфа. К чему бы это? И почему бы это? Вспоминаем, что сегментная часть адреса всегда кратна 16 или 10h. Наша программа занимает больше одного параграфа на 1 байт. Поэтому ассемблер, видя, что сегмент кода занимает больше одного параграфа, но меньше двух, определил сегментную часть адреса сегмента данных на 20h байт (2 параграфа) отстоящую от начала сегмента кода. Соответственно в программе hello.exe сегмент данных начинается на границе параграфа, то есть имеет смещение 0, а в программе hello1.exe, сегмент данных, из-за атрибута выравнивания, имеет смещение в 1 байт (в данном случае), от начала параграфа. Что мы и видим в коде команды mov dx,offset msg.
Теперь поперемещаем сегменты и посмотрим, как это отразится на листинге программы и ее коде. Создадим «новую» программку – hello2.asm. Определим в ней данные перед сегментом кода.





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

Комментариев нет:
Отправить комментарий