我只想了解如何在C程序可执行文件中处理寄存器变量.即在嵌入式系统和X86机器(C台程序中可执行的C程序)中,它在哪个位置(或寄存器)准确存储?
这个观点怎么样?(如果我错了,请纠正我)
假设我们已将函数内的一个变量声明/初始化为'int'数据类型.通常它会进入堆栈段,只有在运行时,当调用者调用包含局部变量的被调用者时,它才会出现在该部分中.但是如果我们将上面的局部变量声明为'register int',那么它也将转到堆栈段.但是在运行时,处理器将堆栈中的局部变量放入其通用寄存器位置(因为'register'关键字导致额外的编译器插入代码)以及从那里快速访问它.
这是它们之间唯一的区别是在运行时访问,并且它们之间没有内存加载差异.
__Kanu
我们正在研究一种模型检查工具,它可以执行几十亿次搜索程序.我们有不同的搜索例程,目前使用预处理器指令进行选择.这不仅非常不方便,因为我们每次做出不同的选择时都需要重新编译,但也使代码难以阅读.现在是开始新版本的时候了,我们正在评估是否可以避免条件编译.
这是一个非常人为的例子,显示了效果:
/* program_define */
#include <stdio.h>
#include <stdlib.h>
#define skip 10
int main(int argc, char** argv) {
int i, j;
long result = 0;
int limit = atoi(argv[1]);
for (i = 0; i < 10000000; ++i) {
for (j = 0; j < limit; ++j) {
if (i + j % skip == 0) {
continue;
}
result += i + j;
}
}
printf("%lu\n", result);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这里,变量skip是影响程序行为的值的示例.不幸的是,我们需要在每次需要新值时重新编译skip.
让我们看看该程序的另一个版本:
/* program_variable */
#include …Run Code Online (Sandbox Code Playgroud) 据我所知,在C中,我们可以使用关键字"register"向编译器建议变量应该存储在CPU寄存器中.CPU指令中涉及的所有变量最终都会存储在CPU寄存器中以供执行,这不是真的吗?
我的for(c ++ .Net Win32控制台)代码中有一个循环,必须尽可能快地运行.所以我需要让编译器使用寄存器而不是将其存储在RAM中.
MSDN说:
register关键字指定变量将存储在机器寄存器中(如果可能).
这是我试过的:
for(register int i = 0; i < Size; i++)
Run Code Online (Sandbox Code Playgroud)
当我查看编译器生成的反汇编代码时,我看到:
012D4484 mov esi,dword ptr [std::_Facetptr<std::codecvt<char,char,int> >::_Psave+24h (12DC5E4h)]
012D448A xor ecx,ecx
012D448C push edi
012D448D mov edi,dword ptr [std::_Facetptr<std::codecvt<char,char,int> >::_Psave+10h (12DC5D0h)]
012D4493 mov dword ptr [Size],ebx
012D4496 test ebx,ebx
012D4498 jle FindBestAdd+48h (12D44B8h) //FindBestAdd is the function the loop is in
012D449A lea ebx,[ebx]
Run Code Online (Sandbox Code Playgroud)
我期望汇编代码不生成dword ptr我使用register关键字的地方.
所以,我怎么会知道,如果有可能的编译器使用寄存器,我应该怎么做才能强制编译器直接读取/从/到寄存器写.
c++ compiler-construction performance assembly cpu-registers
我知道引用已注册变量的地址会导致编译错误.
int main()
{
register int i = 10;
int *a = &i;
printf("%d", *a);
getchar();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
正如预期的那样,gcc由于引用了已注册变量的地址,因此在使用时会出现编译错误i.
那么下面的代码,它做了类似的事情,怎么会导致没有错误呢?
#include<stdio.h>
int *NEXT(register int i)
{
int *ipt;
ipt = &i;
ipt++;
return ipt;
}
main ()
{
int j=2;
printf("%d",(NEXT(j)));
}
Run Code Online (Sandbox Code Playgroud)
编辑:我的gcc版本
i686-apple-darwin11-llvm-gcc-4.2(GCC)4.2.1(基于Apple Inc. build 5658)(LLVM build 2335.15.00)版权所有(C)2007 Free Software Foundation,Inc.这是免费软件; 查看复制条件的来源.没有保修; 甚至不适用于适销性或特定用途的适用性.