我一直在编写一个用于教育目的的最小lua编译器,它将lua代码转换为使用gcc的C中的内联汇编。
一段时间后,当我生成的输出开始变长,C语句中声明的变量和函数的操作数更多时,就会出现此错误。
test.c: In function ‘int main()’:
test.c:100:6: error: more than 30 operands in ‘asm’
);
当谷歌搜索我发现的唯一其他信息是some gcc mailing list from 2008,但他们说没有修复,除了重新编译gcc(我不感兴趣)。
具有讽刺意味的是,我经常甚至没有30个操作数,但我仍然会收到此错误!
这是一个最小的例子(有19个操作数,仍然给我错误)
// Standard functions
void io_read(){}
void io_write(){}
void print(){}
int main(){
// Working vars decl
long _t0, _t1, _t2, _t3, _t4, _t5, _t6, _t7, _t8;
long factorial, i, n, x;
// Strings decl
const char* _s0 = "enter a number:";
const char* _s1 = "*number";
const char* _s2 = "factorial of ";
const char* _s3 = " is ";
asm("" // My inline asm code
: // Output symbols
[_s0] "+g" (_s0),
[_s1] "+g" (_s1),
[_s2] "+g" (_s2),
[_s3] "+g" (_s3),
[_t0] "+g" (_t0),
[_t1] "+g" (_t1),
[_t3] "+g" (_t3),
[_t4] "+g" (_t4),
[_t5] "+g" (_t5),
[_t6] "+g" (_t6),
[_t7] "+g" (_t7),
[_t8] "+g" (_t8),
[factorial] "+g" (factorial),
[i] "+g" (i),
[n] "+g" (n),
[x] "+g" (x)
: // Input symbols
[io_read] "r" (io_read),
[io_write] "r" (io_write),
[print] "r" (print)
: // Clobbers
"cc", "rax", "rbx", "rcx", "rdx"
);
}
我的gcc版本是6.2.1 20160830
提前致谢!
答案 0 :(得分:1)
所以我没有找到问题的直接解决方案,但感谢Ross Ridge我能很好地解决这个问题。
我做的第一个改变就是改变" + g"用" g"在可能的情况。显然" + g"算作两个操作数,因为它允许读取和写入,所以我用" g"只允许写。
此外,我能够将我的函数作为操作数完全删除,方法是将它们移动到全局范围,然后直接调用" call print"而不是"调用%[print]"。但应该注意,这只适用于内联C,不适用于内联C ++。
如果您正在编写像我这样的编译器,我建议远离内联汇编。看起来更麻烦,简单地从Assembler手动调用C函数会更容易,而且我肯定不会使用内联C更大规模地编译。
编辑:我开始强迫" m"和" + m"而不是使用" g"并强制变量到堆栈上似乎工作正常。