简单的汇编示例:设置输入并获得输出 - 正确的语法

时间:2017-05-18 22:53:45

标签: gcc assembly inline-assembly sparc

我尝试做一个简单的例子,在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

感谢您的帮助,问候。

1 个答案:

答案 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" );