M-book

求上得中, 求中得下, 求下得无!
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

2011年8月28日

摘要: volatile关键字是一种类型修饰符,用它声明的类型变量表示可以被某些编译器未知的因素更改。用volatile关键字声明的变量i每一次被访问时,执行部件都会从i相应的内存单元中取出i的值。没有用volatile关键字声明的变量i在被访问的时候可能直接从cpu的寄存器中取值(因为之前i被访问过,也就是说之前就从内存中取出i的值保存到某个寄存器中),之所以直接从寄存器中取值,而不去内存中取值,是因为编译器优化代码的结果(访问cpu寄存器比访问ram快的多)。以上两种情况的区别在于被编译成汇编代码之后,两者是不一样的。之所以这样做是因为变量i可能会经常变化,保证对特殊地址的稳定访问。=====以下 阅读全文

posted @ 2011-08-28 22:57 M-book 阅读(206) 评论(0) 推荐(1)

摘要: 在大型C语言项目工程或者linux内核中我们都会经常见到两个FASTCALL和armlinkage两个标识符(修饰符),那么它们各有什么不同呢?今天就给大家共同分享一下自己的心得.大家都知道在标准C系中函数的形参在实际传入参数的时候会涉及到参数存放的问题,那么这些参数存放在哪里呢? 有一定理论基础的朋友一定会肯定地回答:这些函数参数和函数内部局部变量一起被分配到了函数的局部堆栈中,真的是这样吗?其实还有例外的情况:首 先作为linux操作系统,它不一定就只运行在X86平台下面,还有其他平台例如ARM,PPC,达芬奇等等,所以在不同的处理器结构上不能保证都是通过 局部栈传递参数的,可能此时就有朋 阅读全文

posted @ 2011-08-28 22:57 M-book 阅读(218) 评论(0) 推荐(0)

摘要: linux i386 kernel中:#define fastcall __attribute__((regparm(3)))#define asmlinkage __attribute__((regparm(0))) 函数定义前加宏asmlinkage ,表示这些函数通过堆栈而不是通过寄存器传递参数。 宏asmlinkage定义如下:#define asmlinkage __attribute__((regparm(0))).gcc编译器在汇编过程中调用c语言函数时传递参数有两种方法:一种是通过堆栈,另一种是通过寄存器。缺省时采用寄存器,假如你要在你的汇编过程中调用c语言函数,并且想通过堆栈 阅读全文

posted @ 2011-08-28 22:57 M-book 阅读(235) 评论(0) 推荐(0)

摘要: 在C语言中,static的字面意思很容易把我们导入歧途,其实它的作用有三条。(1)先来介绍它的第一条也是最重要的一条:隐藏。当我们同时编译多个文件时,所有未加static前缀的全局变量和函数都具有全局可见性。为理解这句话,我举例来说明。我们要同时编译两个源文件,一个是a.c,另一个是main.c。下面是a.c的内容char a = 'A'; // global variablevoid msg(){printf("Hello\n");}下面是main.c的内容int main(void){extern char a; // extern variable m 阅读全文

posted @ 2011-08-28 22:56 M-book 阅读(227) 评论(0) 推荐(0)

摘要: 1.内存屏障(memory barrier) #define set_mb(var, value) do { var = value; mb(); } while (0) #define mb() __asm__ __volatile__ ("" : : : "memory")1)set_mb(),mb(),barrier()函数追踪到底,就是__asm__ __volatile__("":::"memory"),而这行代码就是内存屏障。 2)__asm__用于指示编译器在此插入汇编语句 3)__volatile_ 阅读全文

posted @ 2011-08-28 22:56 M-book 阅读(815) 评论(0) 推荐(1)

摘要: 推荐 volatile 提醒编译器它后面所定义的变量随时都有可能改变,因此编译后的程序每次需要存储或读取这个变量的时候,都会直接从变量地址中读取数据。如果没有 volatile关键字,则编译器可能优化读取和存储,可能暂时使用寄存器中的值,如果这个变量由别的程序更新了的话,将出现不一致的现象。下面举例说明。在DSP开发中,经常需要等待某个事件的触发,所以经常会写出这样的程序: short flag; void test() { do1(); while(flag==0); do2(); } 这段程序等待内存变量flag的值变为1(怀疑此处是0,有点疑问,)之后才运行do2()。变量flag的值由 阅读全文

posted @ 2011-08-28 22:56 M-book 阅读(187) 评论(0) 推荐(0)

摘要: typedef在C中真是一个神奇的东西,没有点事例真是很难理解:(回头看看那超烂的大学C教程,很多地方没写清楚,遇到问题时看不懂代码。u-boot中有这么一段代码。/*这里定义了一个新的数据类型init_fnc_t,*这个数据类型是参数为空,返回值为int的函数。*/typedef int (init_fnc_t) (void);/*init_sequence是一个指针数组,指向的是init_fnc_t类型的函数*/init_fnc_t *init_sequence[] = {cpu_init, /* basic cpu dependent setup */board_init, /* bas 阅读全文

posted @ 2011-08-28 22:55 M-book 阅读(219) 评论(0) 推荐(0)

摘要: 1、typedef int (init_fnc_t) (void);表示定义init_fnc_t为函数类型,该函数返回int型,无参数。而“init_fnc_t *init_sequence[]={cpu_init, board_init }”表示用init_fnc_t(函数类型)去定义一个一维指针数组,数组中的元素都是指针变量,而且都是指向函数的指针,这些函数返回值都是int型,无参数的。更明朗的说就是数组中的每个元素是用来存放函数入口首地址的。2、int (*init_fnc_t) (void);表示定义一个函数指针(返回值为int型,无参数的函数指针,存放的是函数的首地址),typede 阅读全文

posted @ 2011-08-28 22:55 M-book 阅读(931) 评论(0) 推荐(0)