首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在内联程序集中使用函数作用域标签

在内联程序集中使用函数作用域标签
EN

Stack Overflow用户
提问于 2012-10-04 15:16:55
回答 2查看 886关注 0票数 0

我在C++中使用gcc-4.7在64位小endian Ubuntu12.04LTS和Eclipse和gdb上使用内联程序集。我所要做的工作的总体方向是为一些深奥的基于堆栈的编程语言制作某种字节码解释器。

在本例中,我一次处理指令4位(实际上这将取决于指令),当没有更多的非零指令(0将是nop)时,我将读取下一个64位的单词。

不过,我想问一问,如何在内联程序集中使用函数作用域标签?

程序集中的标签似乎是全局的,这是不利的,我找不到从汇编语言中跳转到C++函数作用域标签的方法。

下面的代码是我试图做的事情的一个例子(注意注释):

代码语言:javascript
复制
  ...
  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;
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-10-04 18:00:15

请注意gcc内联asm文档中的以下评论:

说到标签,从一个“鸿沟”跳到另一个“鸿沟”是不支持的。编译器的优化器不知道这些跳转,因此它们在决定如何优化时不能考虑它们。

您也不能依赖在一个asm中设置的标志在下一个中可用,因为编译器可能会在它们之间插入一些东西。

使用gcc 4.5及更高版本,您可以使用asm goto来做您想做的事情:

代码语言:javascript
复制
fetch:
  asm("mov (%r8), %r9");
  asm("add $8, %r8");
control:
  asm goto("test %r9, %r9\n\t"
           "jz  %l[fetch]" : : : : fetch);

请注意,所有其他asm都是完全不安全的,因为它直接使用寄存器,而没有在其读/写/重击列表中声明它们,所以编译器可能决定在它们中添加其他内容(尽管vars中包含asm声明--它可能会决定这些寄存器是死的,因为它们从未被使用过)。因此,如果您希望它实际适用于-O1或更高版本,则需要将其编写为:

代码语言:javascript
复制
  ...
  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, %0\n\t"
           "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代码编写它要容易得多:

代码语言:javascript
复制
long *ip, buf, op;

fetch:
  do {
    buf = *op++;
control:
  } while (!buf);
  op = (buf >>= 4) & 0xf;
  switch(op) {
     :
  }  
  goto control;
票数 1
EN

Stack Overflow用户

发布于 2012-10-04 15:45:46

你应该能够做到这一点:

代码语言:javascript
复制
fetch:
  asm("afetch: mov(%r8), %r9");
  ...
  asm("jz afetch");

或者,将标签放在单独的asm("afetch:");中也应该有效。注意避免冲突的不同名称-我不完全确定这是必要的,但我怀疑它是必要的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12730468

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档