2016-08-26 3 views
0

В настоящее время я пишу компилятор для пользовательского asm-подобного языка программирования , и я действительно запутался в том, как сделать соответствующую относительную адресацию данных для информационных меток.PC-относительная адресация на компиляторе, подобном сборке

main LDA RA hello 
     IPT #32 
     HLT 

hello .STR "Hello, world!" 

Псевдокод выше, после компиляции, приводит к следующему: гекс

31 80 F0 20 F0 0C 48 65 6C 6C 6F 2C 20 77 6F 72 6C 64 21 00 

3180, F020 и F00C инструкции в LDA, IPT и HLT.

Как видно из кода, инструкция LDA использует в качестве аргумента метку hello. Который при компиляции становится значением 02, что означает «Incremented PC + 0x02» (если вы посмотрите на код, это расположение строки «Hello, world!» По отношению к вызову LDA. Дело в том, что: .STR не является инструкцией, так как он только сообщает компилятору, что ему нужно добавить строку с завершением (0) в конце исполняемого файла, так что были ли другие инструкции после объявления метки hello, это смещение было бы неправильным.

Но я не могу найти способ вычисления правильного смещения, кроме того, что компилятор может путешествовать во времени. Должен ли я его «скомпилировать» два раза? Сначала для этикеток данных, а затем для фактических инструкций ?

+1

Смещение к объявлению 'hello' не будет изменяться более подробными инструкциями после переменной' .STR'. – kdopen

ответ

2

Да, большинство ассемблеров (по крайней мере) два прохода - именно из-за таких прямых ссылок. Добавление возможностей макроса может добавить больше проходов.

Посмотрите на сборку, а не только на op-коды. Как вы сказали, фактическое смещение равно «2», я предполагаю, что память адресована словом.

0000 3180 main LDA RA hello 
0001 F020   IPT #32 
0002 F00C   HLT 

0003 4865 hello .STR "Hello, world!" 

Первые две колонки - это ПК и код операции. Я не знаю, как LDA инструкция закодирован (где находится +2 смещение там?)

В первом проходе, предполагая, что все решения относительно, то assmebler излучала бы неподвижную часть операционного кода (охватывая часть LDA RA) вместе с маркером, чтобы показать, что ему необходимо исправить инструкцию с адресом hello во втором проходе.

На данный момент он знает размер, но не полную стоимость конечного машинного языка.

Затем он продолжает работу, разрабатывая адрес каждой инструкции и строя свою таблицу символов.

Во втором проходе, зная вышеприведенную информацию, он исправляет каждую инструкцию, вычисляя относительные смещения и т. Д. Он также часто регенерирует весь вывод (включая значения ПК).

Иногда во втором проходе будет обнаружено что-то, что предотвращает его продолжение. Например, возможно, вы можете ссылаться только на объекты в пределах 256 слов (от -127 до +128), но метка hello оказывается более чем на 128 слов. Это означает, что он должен был использовать инструкцию с двумя словами (с абсолютным адресом), которая меняет все, что она узнала во время первого прохода.

Это часто упоминается как ошибка «исправить». То же самое может произойти во время фазы ссылки.

Однопроходные ассемблеры возможны только в том случае, если вы настаиваете на «определении перед использованием». В этом случае ваш код будет сообщать hello как неопределенный символ.

Вам также необходимо прочитать «разделы программы». Пока .STR не является исполняемой инструкцией, то - это директива для ассемблера для размещения двоичного представления строки в секции CODE изображения (против DATA).

+0

Более вероятные смещения, связанные с PC, масштабируются на 2 в машинной кодировке, а не на то, что память является только адресной. Кроме того, в разделе кода исполняемого файла принято вводить данные только для чтения, такие как строки. (например, '.section .rodata' в газе для платформ Unix.) –

+0

Также возможно, но это все еще подразумевает, что нет 8 или 24 бит инструкций. – kdopen

+0

Или вам понадобится не более одного байта прокладки для всего, что вы хотите адресовать, с режимом адресации с помощью ПК. Похоже на то, что с -128 .. + 127B будет довольно небольшим диапазоном, особенно. так как вы обычно хотите немного разделить код и данные. –

Смежные вопросы