В бакалавриате я прошел курс по компиляторам, в котором мы написали компилятор, который компилирует исходные программы на игрушечном Java-подобном языке в игрушечный ассемблер (для которого у нас был переводчик). В проекте мы сделали несколько предположений о целевой машине, тесно связанной с «настоящими» нативными исполняемыми файлами, включая:
- стек времени выполнения, отслеживаемый регистром выделенного указателя стека («SP»)
- куча для динамического выделения объектов, отслеживаемая регистром выделенного указателя кучи («HP»)
- регистр счетчика выделенных программ («ПК»)
- целевая машина имеет 16 регистров
- операции над данными (в отличие, например, от скачков) являются операциями регистр-регистр
Когда мы добрались до подразделения по использованию распределения регистров в качестве оптимизации, меня удивило: каково теоретическое минимальное количество регистров для такой машины? Исходя из наших предположений, вы можете видеть, что в нашем компиляторе мы использовали пять регистров (SP, HP, ПК и два для использования в качестве хранилища для бинарных операций). Хотя такие оптимизации, как распределение регистров, безусловно, могут использовать больше регистров, есть ли способ обойтись с меньшим количеством, сохраняя при этом такие структуры, как стек и куча? Я полагаю, что при адресации регистров (операции от регистра к регистру) нам нужно как минимум два регистра, но нужно ли нам больше двух?