Как создать метку с номером из переменной в asm - PullRequest
0 голосов
/ 13 октября 2018

Я хочу написать JIT-компилятор, который будет основан на интерпретаторе Brainfuck.Весь код программы будет написан на языке C. Я создал все инструкции, кроме циклов.У меня есть идея рассчитать смещения совпадающих скобок цикла, но для этого мне нужно создать локальные метки в asm с уникальными номерами.Но каждое число в имени метки должно быть значением из переменной.Это то, что я хочу сделать в C:

void jit(struct bf_state *state, char *source)
{
    size_t number_of_brackets = 0;

    while (source[state->source_ptr] != '\0')
    {
        switch (source[state->source_ptr])
        { 
            case '[': 
            {
                number_of_brackets++;
                __asm__ ("start_of_the_loop<number_of_brackets>:\n\t"
                         "pushl <number_of_brackets>\n\t"
                         "cmpb $0, (%%rax)\n\t"
                         "je <end_of_the_loop<number_of_brackets>>"
                         : 
                         : "a" (state->memory_segment), "d" (number_of_brackets));
            }
            break;
            case ']': 
            {
                __asm__ ("end_of_the_loop<number_of_brackets>:\n\t"
                         "popl %%edx\n\t"
                         "cmpb $0, (%%rax)\n\t"
                         "jne <start_of_the_loop<number_of_brackets>>"
                         : 
                         : "a" (state->memory_segment), "d" (number_of_brackets));
            }
            break; 
        }
    }
} 

Могу ли я создать метки с номером из переменной в asm?Это мне очень поможет.Буду благодарен за ответ.Заранее спасибо!

1 Ответ

0 голосов
/ 13 октября 2018

Вы не можете безопасно переходить от одного оператора asm к другому.Вы можете использовать asm goto, чтобы сообщить компилятору, что вы можете перейти к метке C вместо того, чтобы провалиться.

Но у вашей идеи смешивания asm и C есть фатальный недостатокчтобы использовать стек вызовов в качестве структуры данных стека: нельзя оставлять rsp измененным в конце оператора asm .Вы нарушите сгенерированный компилятором код, который ссылается на стековую память относительно RSP, потому что -fomit-frame-pointer включен по умолчанию (за исключением -O0).И даже если нет, компилятор предполагает, что он знает, куда указывает RSP, даже в функциях, которые используют указатель кадра.

Кстати, pushl недопустимо в 64-битном коде, только 16 и 64-битном операнде-размеры для push доступны.

Кроме того, если вы собираетесь pop в регистр, вы должны использовать выходной операнд для этого ограничения, а не вход.


Есть еще один фатальный недостаток: inline-asm не может JIT .Весь ассм должен быть там во время сборки.Как и шаблоны C ++, start_of_the_loop<number_of_brackets> не может работать, если number_of_brackets не является константой времени сборки.

...