简单的汇编示例:设置输入并获取输出 - 正确的语法
Simple assembly example : set inputs and get output - right syntax
我试着做一个简单的例子,将一段 Sparc 程序集 32 位插入到 C 代码中;这个小代码对变量 "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 行似乎对应于“asm volatile ("set sum, %g1\n\t" \ ...
”。
但我不知道如何避免这些错误。它可能来自设置为 %g1
寄存器的变量 sum
。
关于属于 C 代码的变量和位于汇编代码部分的变量之间的 links。我还看到,对于输入和输出参数,语法 "=g"
(输出参数??)、"g"
(输入参数):我认为它对应于两种语法之间的不同寄存器。
如果有人可以给我一些线索来理解这个 link 并调试我的小代码,它执行一个简单的循环来递增 variable sum
。
感谢您的帮助,问候。
正如其他人所说,您的内联汇编代码中存在许多错误和误解。这里只是一些事情。首先,在扩展的 asm 语法中,您必须使用另一个“%”转义所有“%”符号,因此例如您需要放置“%%g1”而不是“%g1”,并对您访问的所有寄存器执行此操作。其次,您不能对变量 n 或 sum 使用 'set',因为它们都是堆栈变量,而不是全局变量。您已经在 asm 语句中将这些变量声明为位置参数,因此 sum 是参数 %0,n 是 %1。您的添加指令将结果放在 %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" );
我试着做一个简单的例子,将一段 Sparc 程序集 32 位插入到 C 代码中;这个小代码对变量 "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 行似乎对应于“asm volatile ("set sum, %g1\n\t" \ ...
”。
但我不知道如何避免这些错误。它可能来自设置为 %g1
寄存器的变量 sum
。
关于属于 C 代码的变量和位于汇编代码部分的变量之间的 links。我还看到,对于输入和输出参数,语法 "=g"
(输出参数??)、"g"
(输入参数):我认为它对应于两种语法之间的不同寄存器。
如果有人可以给我一些线索来理解这个 link 并调试我的小代码,它执行一个简单的循环来递增 variable sum
。
感谢您的帮助,问候。
正如其他人所说,您的内联汇编代码中存在许多错误和误解。这里只是一些事情。首先,在扩展的 asm 语法中,您必须使用另一个“%”转义所有“%”符号,因此例如您需要放置“%%g1”而不是“%g1”,并对您访问的所有寄存器执行此操作。其次,您不能对变量 n 或 sum 使用 'set',因为它们都是堆栈变量,而不是全局变量。您已经在 asm 语句中将这些变量声明为位置参数,因此 sum 是参数 %0,n 是 %1。您的添加指令将结果放在 %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" );