我正在跟进this question和this another one。
在第一篇文章中,我可以开始使用以下SPARC内联汇编代码:
#include <stdio.h>
#include <sys/time.h>
#include <unistd.h>
int n;
int sum;
int main ()
{
sum = 0;
n = 1000;
struct timeval tv1, tv2;
long int diff;
gettimeofday (&tv1, NULL);
asm volatile ("set sum, %g1\n\t" \
"ld [%g1], %g2\n\t" \
"set n, %g3\n" \
"ld [%g3], %g4\n\t" \
"loop:\n\t" \
"add %g2, 1, %g2\n\t" \
"subcc %g4, 1, %g4\n\t" \
"bne loop\n\t" \
"nop\n\t"
"st %g2, [%g1]"
);
gettimeofday (&tv2, NULL);
diff = (tv2.tv_sec - tv1.tv_sec) * 1000000L + (tv2.tv_usec - tv1.tv_usec);
printf ("Elapsed time = %ld usec\n", diff);
printf ("Sum = %d\n", sum);
return 0;
}
最终结果是:
Elapsed time = 37 usec
Sum = 1000
这是预期的结果。
我认为,通过使用set sum, %g1
指令,我将sum
变量的地址放入%g1
寄存器中。我对n
执行相同操作,其地址存储在%g3
寄存器中。之后,我将位于地址[%g1]
和[%g3]
的值加载到%g2
和%g4
并处理它们。最后,我将%g2
值存储在变量sum
的地址处,即位于[%g1]
。
我必须尊重的唯一约束是在sum
之外声明n
和int main() function
:如果我将它们声明为int main()
,则编译失败。
Now, I am using another syntax
也用于有关内联汇编代码的手册中 - 第二种语法如下:
asm volatile("Sparc instructions"
: /* output : don't forget "=" */ "=r" (outputX)
: /* input */ "r"(inputX)
: /* no clobbered regs */
);
这是第二篇文章的主题。以下代码工作正常:
#include <stdio.h>
#include <sys/time.h>
#include <unistd.h>
int main ()
{
int sum = 0;
int n = 100000000;
struct timeval tv1, tv2;
long int diff;
gettimeofday (&tv1, NULL);
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");
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 = %ld\n", sum);
return 0;
}
最终结果是:
Elapsed time = 232869 usec
Sum = 100000000
与第一种语法不同,我在第二版中不需要在sum
函数之外声明n
和int main()
变量。
此外,我需要使用另一个'%'来转义所有'%'符号:第一种语法不是这种情况。
除了这些微小的差异之外,我们可以说这两种语法相当于将SPARC内联汇编插入到C代码中吗?
感谢您的发言,问候。