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