我尝试做一个简单的例子,在C代码中插入一个32位的Sparc程序集;这个小代码对变量进行递增" sum"。
代码是:
#include <stdio.h>
#include <sys/time.h>
#include <unistd.h>
int n;
int sum;
int main ()
{
n = 100;
sum = 0;
struct timeval tv1, tv2;
long long diff;
gettimeofday (&tv1, NULL);
asm volatile ("set sum, %g1\n\t" \
"set n, %g3\n" \
"loop:\n\t" \
"add %g1, 1, %g2\n\t" \
"sub %g3, 1, %g4\n\t" \
"bne loop\n\t" \
"nop\n\t" \
: "=r" (sum)
: "r" (n)
);
gettimeofday (&tv2, NULL);
diff = (tv2.tv_sec - tv1.tv_sec) * 1000000L + (tv2.tv_usec - tv1.tv_usec);
printf ("Elapsed time = %d usec\n", diff);
printf ("Sum = %d\n", sum);
return 0;
}
不幸的是,使用gcc4.1.2进行编译会产生以下错误:
loop_dev_for-assembly_code.c: In function #main#:
loop_dev_for-assembly_code.c:18: error: invalid 'asm': invalid operand output code
loop_dev_for-assembly_code.c:18: error: invalid 'asm': operand number out of range
loop_dev_for-assembly_code.c:18: error: invalid 'asm': invalid operand output code
loop_dev_for-assembly_code.c:18: error: invalid 'asm': operand number out of range
loop_dev_for-assembly_code.c:18: error: invalid 'asm': operand number out of range
loop_dev_for-assembly_code.c:18: error: invalid 'asm': operand number out of range
第18行似乎对应于&#34; asm volatile ("set sum, %g1\n\t" \ ...
&#34;。
但我不知道如何规避这些错误。它可能来自设置为sum
寄存器的变量%g1
。
关于属于C代码的变量与汇编代码部分中的本地变量之间的链接。我还看到,对于输入和输出参数,语法"=g"
(输出参数??),"g"
(输入参数):我认为它对应于2语法之间的不同寄存器。
如果有人能给我一些线索来理解这个链接并调试我的小代码,它会做一个简单的循环来增加variable sum
。
感谢您的帮助,问候。
答案 0 :(得分:0)
正如其他人所说,内联汇编代码中存在许多错误和误解。这里只是一些事情。首先,在扩展的asm语法中,必须使用另一个'%'转义所有'%'符号,因此例如,您需要将'%% g1'而不是'%g1'放入,并对您访问的所有寄存器执行此操作。其次,你不能对变量n或sum使用'set',因为它们都是堆栈变量,而不是全局变量。您已经在asm语句中将这些变量声明为位置参数,因此sum是参数%0,n是%1。你的add指令将结果放在%g2中,它永远不会被初始化或在任何地方使用。
我认为整个序列可以更简单地呈现(未经测试):
asm volatile ("clr %%g1\n" \
"loop:\n\t" \
"add %%g1, 1, %%g1\n\t" \
"subcc %1, 1, %1\n\t" \
"bne loop\n\t" \
"nop\n\t" \
"mov %%g1, %0\n" \
: "=r" (sum)
: "r" (n)
: "g1" );