在内联程序集中使用函数范围的标签
Using function-scoped labels in inline assembly
我在64位小端Ubuntu 12.04 LTS上使用gcc-4.7和Eclipse CDT和gdb,在C++中玩内联汇编。我尝试做的事情的总体方向是为一些深奥的基于堆栈的编程语言制作某种字节码解释器。
在这个例子中,我一次处理4位指令(在实践中,这将取决于指令),当没有更多的非零指令时(因为0将是nop),我读取接下来的64位字。
不过,我想问一下,如何在内联程序集中使用函数范围的标签
汇编中的标签似乎是全局的,这是不利的,而且我找不到从汇编语句跳到C++函数范围的标签的方法。
以下代码是我尝试做的一个示例(注意注释):
...
register long ip asm("r8");
register long buf asm("r9");
register long op asm("r10");
...
fetch:
asm("mov (%r8), %r9");
asm("add $8, %r8");
control:
asm("test %r9, %r9");
asm("jz fetch"); // undefined reference to `fetch'
asm("shr $4, %r9");
asm("mov %r9, %r10");
asm("and $0xf, %r10");
switch (op) {
...
}
goto control;
注意gcc内联asm文档中的以下注释:
说到标签,不支持从一个"asm"跳到另一个。编译器的优化器不知道这些跳跃,因此在决定如何优化时,他们不能将它们考虑在内。
您也不能依赖于在一个asm
中设置的标志在下一个中可用,因为编译器可能会在它们之间插入一些
使用gcc 4.5及更高版本,您可以使用asm goto
执行您想要的操作:
fetch:
asm("mov (%r8), %r9");
asm("add $8, %r8");
control:
asm goto("test %r9, %r9nt"
"jz %l[fetch]" : : : : fetch);
请注意,您的asm的所有其余部分都是完全不安全的,因为它直接使用寄存器,而没有在读/写/删除列表中声明它们,因此编译器可能会决定在其中放入其他内容(尽管vars上有asm
声明——它可能会决定这些寄存器已经死了,因为它们从未被使用过)。因此,如果你希望这能真正与-O1或更高版本一起使用,你需要将其写成:
...
long ip;
long buf;
long op;
...
fetch:
asm("mov (%1), %0" : "=r"(buf) : "r"(ip));
asm("add $8, %0" : "=r"(ip) : "0"(ip));
control:
asm goto("test %0, %0nt"
"jz %l[fetch]" : : "r"(buf) : : fetch);
asm("shr $4, %0" : "=r"(buf) : "0"(buf));
asm("mov %1, %0" : "=r"(op) : "r"(buf));
asm("and $0xf, %0" : "=r"(op) : "r"(op));
在这一点上,只将其写成C代码要容易得多:
long *ip, buf, op;
fetch:
do {
buf = *op++;
control:
} while (!buf);
op = (buf >>= 4) & 0xf;
switch(op) {
:
}
goto control;
您应该能够做到这一点:
fetch:
asm("afetch: mov(%r8), %r9");
...
asm("jz afetch");
或者,将标签放在单独的asm("afetch:");
中也可以。注意不同的名称以避免冲突-我不完全确定这是否有必要,但我怀疑是的。
相关文章:
- 是否可以依赖函数范围的静态变量来执行程序关闭期间调用的方法?
- 在函数范围内在堆栈上分配的数组在离开函数时是否总是被释放?
- 在 gcc/clang (C++) 中获取函数范围之外的标签地址
- 函数范围的静态变量如何导致与共享库中函数代码的未来使用不兼容
- 是否未定义将对函数范围变量的引用作为值返回
- 为什么当我的代码超出函数范围时,"does not name a type"出现编译器错误?
- 在函数范围之外的标头中使用 UDL
- 模板化函数范围内的条件模板化类型别名
- 获取提升程序选项以在函数范围之后保留
- C++ 链表 - 插入节点函数不会更新函数范围之外的值
- C++:将参数应用于函数范围
- 为什么基于指针交换两个值在函数范围之外不起作用?
- 类模板中定义的朋友函数范围定义的范围是什么?
- 在内联程序集中使用函数范围的标签
- 检测函数范围之外的未使用变量
- 静态变量生存期、文件范围与函数范围
- 是否可以编写一个在函数范围内使用时会抱怨的宏
- Arduino-setup()中声明的变量不在函数范围内
- C++-函数范围内的函数声明
- 我是否要删除函数范围内的内存?