Имя переменной (или метка) должно заменяться на его смещение, т.е. на адрес имени, отсчитанный от начала того сегмента, в котором описано это имя. Для подсчета смещений ассемблер в своей работе использует специальный счетчик размещения (СР), в котором всегда находится смещение первой свободной, еще не занятой ячейки текущего сегмента, т.е. ячейки, куда должна быть помещена очередная машинная команда. При появлении в программе на ЯА нового сегмента СР обнуляется, а затем увеличивается по мере просмотра предложений этого сегмента.
Рассмотрим такой пример:
имя адрес СР
S SEGMENT 0
A DB ? A <-> 0 1
B DW ? B <-> 1 3
C DD ? C <-> 3 7
...
При появлении директивы SEGMENT отсчет смещений должен начаться от 0, поэтому СР получает значение 0. Далее идет директива DB, описывающая переменную A. Эта переменная размещается с самого начала сегмента, т.е. имеет смещение 0, поэтому имени A ставится в соответствие адрес 0, т.е. текущее значение СР. Переменная A
занимает 1 байт, поэтому СР увеличивается на 1 и имеет значение 1; это значит, что первая свободная ячейка в сегменте имеет адрес 1. С этого места размещается переменная B, поэтому имени B ставится в соответствие адрес 1. Так как на B отводится 2 байта, то СР увеличивается на 2 и теперь имеет значение 3. Именно этот адрес будет поставлен в соответствие имени C из следующей директивы. После этого СР увеличивается на 4, и т.д.
Вот так ассемблер с помощью СР следит за тем, какие ячейки уже заняты, а какие свободны, и с помощью этого СР определяет, какой адрес какому имени соответствует. Эти соответствия запоминаются ассемблером и затем используются для замены имен на адреса.
Такова общая идея перевода с ЯА на машинный язык. Она достаточно проста, но при ее реализации возникает ряд проблем, наиболее важные из которых рассматриваются далее.