Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Финогенов-основы_языка_ассемблера.doc
Скачиваний:
26
Добавлен:
17.09.2019
Размер:
3.35 Mб
Скачать

Глава 2

Рассматривая листинг, можно отметить ряд полезных моментов об­щего характера. Предложения программы с операторами assume, segment, ends, end, как уже отмечалось ранее, не транслируются в какие-либо ма­шинные коды и не находят отражения в памяти. Они нужны лишь для передачи транслятору служебной информации о способе трансляции ко­манд (assume), границах сегментов (segment и end) и строке, на которой следует завершить обработку исходного текста (end).

Каждому транслируемому предложению программы соответствует оп­ределенное смещение, причем задание смещений выполняется в каждом сегменте в отдельности. Первая команда mov AX,data имеет смещение от начала сегмента команд, равное нулю. Она занимает 3 байта, поэтому сле­дующая команда начинается с байта 3 и имеет соответствующее смещение. Транслятор не смог полностью определить код команды mov AX,data. В этой команде в регистр АХ засылается сегментный адрес сегмента data. Однако этот адрес станет известен лишь в процессе загрузки выполнимо­го файла программы в память. Поэтому в листинге на месте этого адреса стоят нули, помеченные буквой s, напоминающей о том, что здесь дат-жен быть пока неизвестный сегментный адрес.

Еще одна помеченная команда с кодом ВА 0000 располагается в стро­ке 8 листинга. В этой команде в регистр DX заносится смещение поля с именем msg, расположенное в сегменте данных (ключевое слово offset, указанное перед именем поля, говорит о том, что-речь идет не о содержи­мом ячейки msg, а об ее смещении). Поле msg расположено в самом нача­ле сегмента данных, и его смещение от начала сегмента равно 0, что и указано в коде команды. Почему же эта команда помечена буквой г, явля­ющейся сокращением слова relocatable, перемсстимый'

Чтобы ответить на этот вопрос, нам придется рассмотреть, как сег­менты программы размещаются в памяти. Как уже говорилось, любой сег­мент может располагаться в памяти только с адреса, кратного 16, т.е. на границе 16-байтового блока памяти (параграфа). Конкретный адрес про­граммы в памяти зависит от конфигурации компьютера, — какой размер занимает DOS, сколько загружено резидентных программ и драйверов, а также в каком режиме запускается программа — в отладчике или без него. Предположим, что сегментный адрес сегмента команд оказался равным 1306И (рис. 2.2, а). В нашей программе сегмент команд имеет размер llh байт (что указано в строке 13 листинга), т.е. занимает целый параграф плюс один байт. Сегмент данных имеет размер 14h байт (строка 19 лис­тинга) и тоже требует для своего размещения немного больше одного параграфа. Из-за того, что сегмент данных должен начаться на границе параграфа, ему будет назначен сегментный адрес 1308h и между сегмен­тами образуется пустой промежуток размером 15 байт.

Потеря 15 байт из многомегабайтовой памяти, разумеется, не имеет никакого значения, однако в некоторых случаях, например, при компо­новке единой программы из большого количества модулей с небольшими по размеру подпрограммами, суммарная потеря памяти может оказаться значительной.

Основы программирования

Сегментные Сегментные

адреса 1306Н

Смещения адрес 0 1306h

1

2

i Смешения

Л

1 Сегмент команд

i

1 Сегмент команд

0 Смещения 1

2 Ё =

1307Н

'

Команды

г

I0h 1307Ь е место

>

Команды

t

ЮН

*-* — ° В листи (*> ь» — В памят

t

1 Сегмент данных

t . Пуск

между

сегментами

Данные

1308Н

ч г Смещения

'

'

«h llh

13h 14h

i

Сегмент данных

Данные

0 I308H 1

2

130%

10h 1309H

ч

'

13h

Рис. 2.2. Расположение сегментов программы в памяти при выравнивании по умолчанию (а) и на байт (б).

byte

data

Для того, чтобы устранить потери памяти, можно сегмент данных объявить с выравниванием на байт:

segment

Такое объявление даст возможность системе загрузить сегмент данных так, как показано на рис. 2.2, б. Сегмент данных частично перекрывает сегмент команд, начинаясь на границе его последнего параграфа (в на­шем случае по адресу 1307h). Для того, чтобы данные не наложились на последние команды сегмента команд, они смещаются вниз так, что начи­наются сразу же за сегментом команд. В нашем примере, где сегмент ко­манд «выступает» за сегментный адрес 1307И всего на 1 байт, данные и надо сместить на этот 1 байт. В результате поле msg, с которого начинается сегмент данных, и которое в листинге имело смещение 0, получит сме­щение 1. Вес остальные адреса в сегменте данных также сместятся на один байт вперед.

В результате данные будут располагаться в физической памяти вплот­ную за командами, без всяких промежутков, однако все обращения в сег-

44