CodeNet / Языки программирования / Ассемблер / СПРАВОЧНИК по системе программирования ТУРБО АССЕМБЛЕР 2.0
СПРАВОЧНИК по системе программирования ТУРБО АССЕМБЛЕР 2.0
Директива SEGMENT ----------------------------------------------------------------- Директива SEGMENT определяет начало сегмента. Метка, которая указывается в данной директиве, определяет начало сегмента. Нап- ример, директива: Cseg SEGMENT определяет начало сегмента с именем Cseg. Директива SEGMENT может также (необязательно) определять атрибуты сегмента, включая вы- равнивание в памяти на границу байта, слова, двойного слова, па- раграфа (16 байт) или страницы (256 байт). Другие атрибуты вклю- чают в себя способ, с помощью которого сегмент будет комбиниро- ваться с другими сегментами с тем же именем и классом сегмента. Директива ENDS ----------------------------------------------------------------- Директива ENDS определяет конец сегмента. Например: Cseg ENDS завершает сегмент с именем Cseg, который начинался по директиве SEGMENT. При использовании стандартных директив определения сег- ментов вы должны явным образом завершать каждый сегмент. Директива ASSUME ----------------------------------------------------------------- Директива ASSUME указывает Турбо Ассемблеру, что в значение какого сегмента установлен данный сегментный регистр. Директиву ASSUME CS: требуется указывать в каждой программе, в которой ис- пользуются стандартные сегментные директивы, так как Турбо Ас- семблеру необходимо знать о сегменте кода для того, чтобы устано- вить выполняемую программу. Кроме того, обычно используются директивы ASSUME DS: и ASSUME ES:, благодаря которым Турбо Ас- семблер знает, к каким ячейкам памяти вы можете адресоваться в данный момент. Директива ASSUME позволяет Турбо Ассемблеру проверить допус- тимость каждого обращения к именованной ячейке памяти с учетом значения текущего сегментного регистра. Рассмотрим следующий при- мер: . . . Data1 SEGMENT WORD 'DATA' Var1 DW 0 Data1 ENDS . . . Data2 SEGMENT WORD 'DATA' Var2 DW 0 Data2 ENDS Code SEGMENT WORD 'CODE' ASSUME CS:Code ProgramStart: mov ax,Data1 mov ds,ax ; установить DS в Data1 ASSUME DS:Data1 mov ax,[Var2] ; попытаться загрузить Var2 в AX ; это приведет к ошибке, так как ; Var2 недоступна в сегменте ; Data1 . . . mov ah,4ch ; номер функции DOS для ; завершения программы int 21h ; завершить программу Code ENDS END ProgramStart Турбо Ассемблер отмечает в данной программе ошибку, так как в ней делается попытка получить доступ к переменной памяти Var2, когда регистр DS установлен в значение сегмента Data1 (к Var2 нельзя адресоваться, пока DS не будет установлен в значение сег- мента Data2). Важно понимать, что Ассемблер на самом деле не знает, что регистр DS установлен в значение Data1. С помощью директивы ASSUME вы указали Турбо Ассемблеру, что нужно сделать такое допу- щение. Директива ASSUME дает вам способ в любой момент сообщить Ассемблеру о значении сегментного регистра, после чего Турбо Ас- семблер будет сообщать вам, если вы пытаетесь сделать невозмож- ное. Однако Турбо Ассемблер не может перехватывать все подобные ошибки. Когда в ссылке на память используется именованная пере- менная памяти (такая, как Var1 и Var2 в предыдущем примере), Тур- бо Ассемблер может проверить допустимость этой ссылки, так как каждая именованная переменная памяти явным образом связана с сег- ментом. Невозможно сообщить Турбо Ассемблеру, к какому сегменту пытается обратиться инструкция: mov al,[bx] В этом случае Турбо Ассемблер должен предположить, что зна- чение сегментного регистра DS соответствует тому сегменту, к ко- торому вы хотите обратиться. Если в данный момент сегментный регистр не указывает ни на какой именованный сегмент, то чтобы сообщить об этом Ассемблеру, можно использовать в директиве ASSUME ключевое слово NOTHING. Например: . . . mov ax,0b800h mov ds,ax ASSUME ds:NOTHING . . . Здесь регистр DS устанавливается таким образом, чтобы указы- вать на цветной графический экран, а затем Турбо Ассемблеру сооб- щается, что регистр DS не указывает ни на какой именованный сег- мент. Вот еще один способ ссылки на цветной графический экран: . . . ColorTextSeg SEGMENT AT 0B8000h ColorTextMemory LABEL BYTE ColorTextSeg ENDS . . . mov ax,ColorTextSeg mov ds,ax ASSUME ds:ColorTextSeg . . . Обратите внимание, что в директиве AT, которая следует за директивой SEGMENT, задается явный начальный адрес сегмента. Сделаем последнее замечание по директиве ASSUME: в некоторых случаях она может привести к тому, что Турбо Ассемблер будет ис- пользовать для доступа к памяти не тот сегментный регистр, кото- рый вы ожидаете, а другой. Рассмотрим, например, следующий фраг- мент программы: . . . Data1 SEGMENT WORD 'DATA' Var1 DW 0 Data1 ENDS Data2 SEGMENT WORD 'DATA' Var2 DW 0 Data2 ENDS Code SEGMENT WORD 'CODE' ASSUME CS:Code ProgramStart: mov ax,Data1 mov ds,ax ; установить DS в Data1 ASSUME DS:Data1 mov ax,Data2 mov es,ax ; установить ES в Data2 ASSUME ES:Data2 mov ax,[Var2] ; загрузить Var2 в AX - ; Турбо Ассемблер укажет ; процессору 8086, что ; загрузку нужно выполнять ; относительно ES, так как ; к Var2 нельзя получить ; доступ относительно DS . . . mov ah,4ch ; функция DOS завершения ; работы программы int 21h ; завершить программу Code ENDS END ProgramStart Данный пример должен быть вам знаком: это модифицированная версия фрагмента программы, использованного нами ранее для того, чтобы показать, как директива ASSUME позволяет Турбо Ассемблеру указать вам, когда вы пытаетесь использовать недопустимую ссылку на память. Однако в данном примере сообщение об ошибке не выво- дится. Но это не означает, что Турбо Ассемблер позволяет вам сде- лать ошибку. Он модифицирует инструкцию: mov ax,[Var2] для доступа к Var2 относительно сегментного регистра ES, а не сегментного регистра DS. Это происходит по следующим причинам. Две директивы ASSUME информируют Турбо Ассемблер о том, что регистр DS установлен в значение сегмента Data1, а ES установлен в значение сегмента Data2. Турбо Ассемблер совершенно правильно заключает, что к Var2 нельзя получить доступ относительно регистра DS, однако Var2 дос- тупно относительно сегментного регистра ES. В итоге Турбо Ассем- блер включает перед инструкцией MOV специальный код (префикс пе- реопределения сегмента), чтобы указать процессору 8086, что вмес- то сегментного регистра DS нужно использовать сегментный регистр ES. Какое все это имеет для вас значение? Это значит, что если вы корректно используете директивы ASSUME, позволяя Турбо Ассем- блеру узнать о текущих установленных для регистров DS и ES значе- ниях, то он может автоматически вам помочь, проверяя возможность доступа к именованным переменным в памяти и в некоторых случаях даже может выполнить автоматическую корректировку сегмента. Общее обсуждение префиксов переопределения сегментов и стан- дартные директивы определения сегментов обсуждаются в Главе 10.