如何使用asm中的变量中的数字创建标签

时间:2018-10-13 19:43:38

标签: c assembly jit brainfuck

我想编写将基于Brainfuck解释器的JIT编译器。程序的整个代码将用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 :(得分:1)

您不能安全地从一个asm语句跳转到另一个。您可以使用asm goto来告诉编译器,您可能会跳转到C标签而不是失败。

但是您的整个想法存在致命缺陷,那就是将asm和C混合使用以将调用堆栈用作堆栈数据结构:您不能在asm语句的末尾修改rsp 。您将破坏编译器生成的代码,这些代码引用相对于RSP的堆栈内存,因为默认情况下-fomit-frame-pointer处于启用状态(-O0除外)。即使没有,编译器仍假定即使在使用帧指针的函数中,RSP仍指向何处。

顺便说一句,pushl在64位代码中是非法的,push仅提供16和64位操作数大小。

此外,如果要将pop放入寄存器,则应将输出操作数用于该约束,而不是输入。


还有另一个致命缺陷: inline-asm无法JIT 。所有asm必须在构建时存在。就像C ++模板一样,如果start_of_the_loop<number_of_brackets>不是汇编时间常量,number_of_brackets就无法工作。