Embedded 使用寄存器的输入设置

Embedded 使用寄存器的输入设置,embedded,register-allocation,Embedded,Register Allocation,我有一个简单的c程序来打印n个斐波那契数,我想把它编译成ELF对象文件。我不想直接在我的c代码中设置斐波那契数(n),我想在寄存器中设置它们,因为我在模拟ARM处理器。我该怎么做 下面是代码片段 #include <stdio.h> #include <stdlib.h> #define ITERATIONS 3 static float fib(float i) { return (i>1) ? fib(i-1) + fib(i-2) : i; }

我有一个简单的c程序来打印n个斐波那契数,我想把它编译成ELF对象文件。我不想直接在我的c代码中设置斐波那契数(n),我想在寄存器中设置它们,因为我在模拟ARM处理器。我该怎么做

下面是代码片段

#include <stdio.h>
#include <stdlib.h>

#define ITERATIONS 3

static float fib(float i) {
    return (i>1) ? fib(i-1) + fib(i-2) : i;
}

int main(int argc, char **argv) {

    float i;
    printf("starting...\n");

    for(i=0; i<ITERATIONS; i++) {
    printf("fib(%f) = %f\n", i, fib(i));
    }

    printf("finishing...\n");

    return 0;
}
#包括
#包括
#定义迭代3
静态浮动fib(浮动i){
返回值(i>1)?fib(i-1)+fib(i-2):i;
}
int main(int argc,字符**argv){
浮点数i;
printf(“开始…\n”);

对于(i=0;i使迭代成为一个变量而不是一个文字常量,那么您可以在循环执行之前直接在调试器/模拟器的“监视”或“局部变量”窗口中设置其值

或者,既然您似乎支持stdio,为什么不通过控制台输入接受该值呢?

可以使用register关键字向编译器建议它为迭代器使用寄存器和迭代次数:

register float i;
register int numIterations = ITERATIONS;
但这不会有多大帮助。首先,编译器可能会使用您的建议,也可能不会使用您的建议。接下来,仍然需要将值放置在堆栈上,以便调用fib(),最后,根据您在循环中调用的函数,过程中调用的代码可以将寄存器内容保存在过程入口的堆栈帧中,并将其作为实现过程返回的代码的一部分进行恢复

如果您真的需要让每一条指令都有价值,那么您将需要编写机器代码(使用汇编语言)。这样,您就可以直接控制寄存器的使用。汇编语言编程不适合胆小的人。汇编语言的开发速度比使用高级语言慢几倍,插入错误的风险更大,并且更难跟踪。高级语言的开发是有原因的,开发C语言是为了帮助编写Unix。运行第一个Unix系统的小型计算机速度非常慢,但使用C而不是汇编的原因是,即使在那时,编写代码所花的时间更少,错误更少,并且比汇编程序更容易调试的代码更为重要

如果你想试试这个,那可能会有帮助

您可以采取的一种策略是将性能关键型代码隔离到一个过程中,用C语言编写过程,捕获生成的汇编语言表示形式。然后重写汇编程序以提高效率。彻底测试,并至少让另一组眼球查看生成的代码


祝你好运!

什么寄存器?这与程序中的任何内容都对应吗?斐波那契序列是一个正整数序列,
float
在这种情况下可能是不合适的类型。它不能准确地表示超过6个有效小数位数的值。
无符号长
无符号长long
将是更好的选择,并且由没有FPU的ARM更有效地计算。@Clifford*如果他需要更大的数字,他可以使用double,并使用封闭形式的解决方案进行计算。@Jay:这将提供更大的范围,但对于>15位数字仍然不精确。如果你不精确地计算Fibonacci数,它就不是真正的Fibonacci数字。A
uint64_t
或64位
无符号长
适合19位数字(log10(pow(2,64))。@Raja——我感觉我没有抓住你问题的重点——你似乎对生成斐波那契数的最有效方法不感兴趣,似乎你更感兴趣的是如何引导“C”编译器(和链接器)为了最有效地利用寄存器,它可以。这是正确的吗?我假设他只是想在模拟器运行时修改迭代计数。这不需要寄存器,只需要变量。此外,
寄存器
限定符将被大多数编译器忽略,并且肯定不会指定任何特定的寄存器。在ARM ABI中,函数的前四个参数在R0-R3中传递(除非
double
long
),并且进一步的参数被叠加。我确实向编译器建议,而不是指示编译器为变量使用寄存器。谢谢。但我不需要超过150个fibonacci数。正如在另一条评论中提到的,我刚刚以fibonacci为例,检查如何将数计数传递到寄存器,而不是在代码本身中声明它。我正在验证两种方法的计时结果1)通过声明变量并为其赋值来在代码中传递它,2)通过在代码中声明数字计数器变量,并在编译时在寄存器中为其赋值。程序的结果或输出无关紧要。这完全是时间问题。@Raga:你在为小事情操心。高效的循环代码是编译器的工作,你的分析将花费比任何节省的时间多得多的时间g可能会在产品的生命周期内实现!如果您正在测量性能,则不应在循环中使用
printf
,循环可能会将95%的时间花费在
printf
中大部分代码所在的位置。相反,将结果存储在数组中,然后打印或在调试器中观察它们。即使d与在
fib()中花费的时间相比,在终止测试中节省的分钟将是微不足道的
函数。我可以将迭代设置为一个变量。这个示例只是为了演示我正在使用的模拟器的工作。我模拟的真实程序更复杂,而且完全是嵌入式的。因此使用控制台输入没有帮助。我实际上是在模拟同一程序的两种配置1)通过寄存器设置输入,2)设置我正在使用ARM7处理器的OVP模拟器。调试器windows是什么意思?我正在使用Msys开发环境来