КАТЕГОРИИ: Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748) |
Директивы определения сегментов. Директива ASSUME
Рассмотрим, как сегментирование проявляется в программах на ассемблере. Для того чтобы указать, что некоторая группа предложений программы на ассемблере образуют единый сегмент памяти, они оформляются как программный сегмент: перед ними ставится директива SEGMENT, после них - директива ENDS, причем в начале обеих этих директив должно быть указано одно и то же имя, играющее роль имени сегмента. Синтаксис директивы SEGMENT: <Имя сегмента> SEGMENT [<параметры>] < Предложение > ... <Предложение > <Имя сегмента> ENDS Директива SEGMENT может содержать три основных типа необязательных параметров, определяющих выравнивание (align), объединение (combine) и класс (‘class‘), между которыми должен быть хотя бы один пробел в качестве разделителя. Эти параметры имеют смысл при разработке больших ассемблерных программ. Программа же в целом представляет собой последовательность таких программных сегментов, в конце которой указывается директива конца программы END. Например: DT1 SEGMENT; программный сегмент с именем DT1 A DB 0 B DW? DT1 ENDS ; DT2 SEGMENT; программный сегмент DT2 C DB 'hello' DT2 ENDS ; CODE SEGMENT; программный сегмент CODE ASSUME CS:CODE, DS:DT1, ES:DT2 BEG: MOV AX,DT2 MOV DS,AX MOV BH,C ... CODE ENDS END BEG; конец текста программы
Предложения программного сегмента ассемблер размещает в одном сегменте памяти (в совокупности они не должны занимать более 64Кб) начиная с ближайшего свободного адреса, кратного 16. Номер (первые 16 битов начального адреса) этого сегмента становится значением имени сегмента. В ассемблере это имя относится к константным выражениям, а не адресным, в связи с чем в команде MOV AX, DT2 второй операнд является непосредственным, поэтому в регистр AX будет записано начало (номер) сегмента DT2, а не содержимое начальной ячейки этого сегмента.
Имена же переменных (A, B, C) и метки (BEG) относятся к адресным выражениям, и им ставится в соответствие адрес их ячейки относительно "своего" сегмента: имени A соответствует адрес 0, имени B - адрес 1, имени C - адрес 0, а метке BEG - адрес 0. Все ссылки на предложения одного программного сегмента ассемблер сегментирует по умолчанию по одному и тому же сегментному регистру. По какому именно - устанавливается специальной директивой ASSUME. Формат директивы ASSUME: ASSUME сегм_регистр1<:имя1 >[, сегм_регистр2:имя2… ] В нашем примере эта директива определяет, что все ссылки на сегмент CODE должны, если явно не указан сегментный регистр, сегментироваться по регистру CS, все ссылки на DT1 - по регистру DS, а все ссылки на DT2 - по регистру ES. Встретив в тексте программы ссылку на какое-либо имя (например, на имя C в команде MOV AX, C), ассемблер определяет, в каком программном сегменте оно описано (у нас - в DT2), затем по информации из директивы ASSUME узнает, какой сегментный регистр поставлен в соответствие этому сегменту (у нас - это ES), и далее образует адресную пару из данного регистра и смещения имени (у нас - ES:0), которую и записывает в формируемую машинную команду. При этом ассемблер учитывает используемое в ПК соглашение о сегментных регистрах по умолчанию: если в адресной паре, построенной им самим или явно заданной в программе, сегментный регистр совпадает с регистром по умолчанию, то в машинную команду заносится лишь смещение. Если, скажем, в нашем примере встретится команда MOV CX,B, тогда по имени В ассемблер построит пару DS:1, но раз операнд-адрес команды MOV по умолчанию сегментируется по регистру DS, то записывать этот регистр в машинную команду излишне и ассемблер записывает в нее только смещение 1. Таким образом, директива ASSUME избавляет программистов от необходимости выписывать полные адресные пары не только тогда, когда используются сегментные регистры по умолчанию (как в случае с именем B), но тогда, когда в машинной команде нужно было бы явно указать сегментный регистр (как в случае с именем C). В ассемблере сегментный регистр в ссылке на имя требуется указывать лишь тогда, когда имя должно по каким-либо причинам сегментироваться по регистру, отличному от того, что поставлен в соответствие всему сегменту, в котором это имя описано.
Однако все это справедливо только при соблюдении следующих условий. Во-первых, директива ASSUME должна быть указана перед первой командой программы. В противном случае ассемблер, просматривающий текст программы сверху вниз, не будет знать, как сегментировать имена из команд, расположенных до этой директивы, и потому зафиксирует ошибку. Во-вторых, в директиве ASSUME следует каждому сегменту ставить в соответствие сегментный регистр: если ассемблеру встретится ссылка на имя из сегмента, которому не соответствует никакой сегментный регистр, то он зафиксирует ошибку. Правда, в обоих случаях можно избежать ошибки, но для этого в ссылках необходимо явно указывать сегментный регистр.
Дата добавления: 2014-11-09; Просмотров: 698; Нарушение авторских прав?; Мы поможем в написании вашей работы! Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет |