Существует несколько ассемблеров для различных платформ, которые, учитывая исходный файл, будут генерировать выходной двоичный файл напрямую, который предназначен для загрузки по определенному адресу. Такие ассемблеры были популярны для некоторых небольших микроконтроллеров или для некоторых исторических процессоров, таких как 6502 и Z80. При сборке программы необходимо знать адрес, где она должна находиться; использование другого адреса потребовало бы повторной сборки программы. С другой стороны, сборка в такой системе была одношаговой. Запустите ассемблер для исходного кода и получите исполняемый вывод. В некоторых случаях было бы возможно иметь исходный код, ассемблер и выводить все сразу в память (на моем Commodore 64 я использовал ассемблер, который был опубликован в журнале Compute Gazette, который так работал).
Хотя повторная сборка всего в любое время, когда изменения адреса могут быть полезны для программы, которая «захватит компьютер», во многих случаях желательно использовать многошаговый процесс, где исходные файлы обрабатываются в файлы объектного кода, которые содержат собранные инструкции, но также содержат различную «символическую» информацию о них; эти файлы затем обрабатываются различными способами, чтобы либо получить образ памяти, который может быть загружен непосредственно в память, либо объединенный перемещаемый объектный файл, который загрузчик операционной системы будет знать, как настроить для любого адреса, по которому он может быть загружен .
Чтобы система связывания объектов была полезной, она должна позволять откладывать определенные виды вычислений адресов до тех пор, пока программа не будет связана или загружена. Некоторые системы позволяют выполнять исключительно простые вычисления во время соединения / загрузки, в то время как другие допускают более сложные вычисления. Более простые схемы могут быть более эффективными, когда они работоспособны, но их ограничения могут привести к обходным решениям. Например, подпрограмма, которая будет использовать BX для циклического прохождения структуры данных с длиной менее 256 байтов, может быть записана примерно так:
mov bx,StartAddr
LP:
мов ал, [bx]
... сделать некоторые вычисления
inc bx
cmp bl, <(StartAddr + Length); <префиксный оператор означает "LSB of"
JNZ LP </p>
Можно было бы использовать cmp bx,(StartAddr+Length)
, но если бы инструменты компиляции могли это поддерживать, сравнение только младшего байта было бы быстрее. С другой стороны, некоторые виды 16-битных инструментов сборки / компоновки могут требовать, чтобы все исправления адресов выполнялись с 16-битными адресами, хранящимися в коде.
Поскольку разные системы допускают разные функции в своих форматах объектного кода, им требуются разные функции на языках ассемблера для управления ими. Наборы инструкций могут быть указаны изготовителем микросхемы, но, как правило, функции для выражения вычисляемых перемещаемых адресов не являются.