АССЕМБЛЕР. Компоновщик. Загрузчик. Макрогенератор


Особые случаи на первом проходе. - часть 2


Как видно, и здесь из-за ссылки вперед ассемблер не знает, что ему делать уже на 1-м проходе. Однако фиксировать в данной ситуации ошибку неразумно, т.к. в реальных программах такие ситуации встречаются очень часто и этих ошибок было бы слишком много. Кроме того, в данной ситуации можно сделать вполне разумное предположение относительно имени P, а именно предположить, что это имя близкой

процедуры (так чаще всего и бывает в реальных программах). Учитывая все это, ассемблер в данной ситуации не фиксирует ошибку, а делает предположение, что P - это имя близкой процедуры, и далее уже действует согласно этому предположению, т.е. считает, что данная команда CALL будет транслироваться в машинную команду близкого вызова, и потому увеличивает СР на 3. Но если затем окажется, что это предположение ошибочно (как в нашем примере), тогда ассемблер уже зафиксирует ошибку.

Третий случай. Предположим, в программе переменная X

описана в конце сегмента команд. Тогда имя X

будет использовано в команде ADD до своего описания:

         ADD X,K

          ...

       X DW Y

Встретив команду ADD, ассемблер еще не будет знать, что обозначает имя X (переменную или что-то иное), и не будет знать, в каком сегменте описано имя X, а потому не будет знать, по какому сегментному регистру должно сегментироваться это имя, надо или нет перед этой командой ставить префикс. А от всего этого зависит, сколько байтов в памяти займет соответствующая машинная команда - 6 или 7.

И здесь ассемблер не фиксирует ошибку, а предполагает, что имя X

обозначает переменную (а не константу или что-то иное) и что в данной команде не должен использоваться префикс, т.е. что переменная X будет описана в сегменте, на начало которого показывает регистр, подразумеваемый по умолчанию в данной команде. Сделав такое предположение, далее ассемблер действует уже согласно ему, а именно определяет, что эта команда в целом займет в памяти 6 байтов. И опять же, если это предположение окажется ошибочным (например, у нас имя X описано в сегменте команд и потому должно сегментироваться по регистру CS), то затем будет зафиксирована ошибка.

Таковы основные случаи, когда из-за ссылок вперед ассемблер уже на 1-м проходе не знает в точности, что ему делать. Как видно, реакция ассемблера на эти случаи может быть двоякой. Если он не может сделать никаких разумных предположений относительно ссылки вперед (как в случае с константами), то он фиксирует ошибку; при этом в ЯА вводятся соответствующие ограничения. Но если можно сделать какое-то разумное предположение относительно ссылки вперед, то ассемблер делает такое предположение и далее действует согласно ему. Отметим, что эти предположения берутся не "с потолка": из всех возможных интерпретаций ссылки вперед в качестве предположения берется вариант, который наиболее часто встречается в реальных программах. Например, процедуры чаще всего бывают близкими, и именно этот вариант выбирается в команде CALL.




Начало  Назад  Вперед



Книжный магазин