Пишу свой собственный C++ компилятор.. застрял на переменных

В настоящее время я работаю над компилятором C++ для моего процессора Logisim в JS, и теперь у меня проблема с переменными:

Я определил пространство в оперативной памяти для хранения данных / значений, и я определил пространство для хранения адресов в пространстве данных. У меня есть регистр nx с указателем на последнюю переменную и регистр mx с указателем на последнюю оперативную память для хранения данных. Но я не знаю, как получить к ним доступ, например, здесь:

модифицированный код C++:

int *pointer_test;
int test;
test = 123;
pointer_test = &test;
*pointer_test = 25;

Pre-сборщик

//Allocate new variable       <---  int *pointer_test;
add nx, 1
//Set the pointer pointing to zero
sram nx, 0


//Allocate another variable   <---  int test;
add nx, 1
//Allocate new storage for the variable
add mx, 1

//Let the variable point to the data <--- test = 123;
sram nx, mx
sram mx, 123

Как мне реализовать сейчас:

pointer_test = &test; 

У меня есть только значение &test, сохраненное в nx, потому что это последняя объявленная переменная, но не адрес переменной / указателя "pointer_test" ...

1 ответ

Решение

Возможно, вы захотите написать сборку на основе стека, как и любой другой компилятор C за последние 20 лет. Это означает, что в ОЗУ имеется область данных, называемая стеком, представляющая собой очередь FIFO, которая расширяется. Стеки также всегда включают хотя бы один регистр: указатель стека. Указатель стека указывает на текущее место в стеке, куда пойдет следующая вещь. Итак, чтобы добавить что-то в стек, вы помещаете его туда, куда указывает указатель стека, а затем вычитаете размер этого элемента из указателя стека.

Другой регистр, который чаще всего используется в ассемблере C, это базовый указатель. Базовый указатель указывает на начало текущего кадра. Кадр можно приблизительно сравнить с областью действия в C. Итак, если у меня есть этот код:

int a;
{
  int b;
}

И верхний стек равен 0x9999, затем a будет в 0x9995 (при условии 4 байта int), указатель стека теперь указывает на 0x9991, а базовый указатель все еще в 0x9999. Когда вводится новая область, базовый указатель перемещается в указатель стека, а затем B устанавливается в 0x9991. Затем, когда выходит из области действия, указатель стека устанавливается на базовый указатель, эффективно стирая переменные в нижней области действия.

Я никогда не слышал об архитектуре, для которой вы программируете, но просто знаю, что подойдут любые два регистра, но некоторые архитектуры, такие как x86, имеют специальные регистры stak (ebp, esp на 32 бит и reb а также rsp на 64 бит).

Но чтобы ответить на этот вопрос немного подробнее, задача компилятора состоит в том, чтобы узнать, какое смещение в стеке имеет каждая переменная, поэтому он может выполнять такие действия, как (псевдокод):

base_pointer - 5 (Offset for pointer_test) = base_pointer - 4 (offset for test)
Другие вопросы по тегам