嵌入天地

----->>>>>嵌入式 文学 管理 米国 卡通 以及其他

公益广告:你可知道,看帖回复和评论是一种美德!

另,兄弟姐妹们,假如有技术问题交流,请直接发送到我的信箱!

博客园 首页 新随笔 联系 订阅 管理

一:相关语言部分
    1.写出运行结果:
        {// test2
          union V {
            struct X {
            unsigned char s1:2;
            unsigned char s2:3;
            unsigned char s3:3;
            } x;
       
            unsigned char c;
          }v;
       
          v.c = 100;
          printf("%d", v.x.s3);
       
        }
    第一个成员定义应该在低位置。
    3
   
------------------------------------------------------------------------------
    2:用C++写个程序,如何判断一个操作系统是16位还是32位的?不能用sizeof()函数

        A1:
            16位的系统下,
            int i = 65536;
            cout << i; // 输出0;
            int i = 65535;
            cout << i; // 输出-1;
       
        32位的系统下,
            int i = 65536;
            cout << i; // 输出65536;
            int i = 65535;
            cout << i; // 输出65535;
       
        A2:
            int a = ~0;
            if( a>65536 )
            {
              cout<<"32 bit"<<endl;
            }
            else
            {
              cout<<"16 bit"<<endl;
            }
           
------------------------------------------------------------------------------           
    3:试编写函数判断计算机的字节存储顺序是开序(little endian)
       还是降序(bigendian)
      
       解释:
         对于字节,按通常顺序依次在内存中存放。
         对于字或双字,在该字(或双字)的内部,则按“倒字存放” 原则存储(little_endian),
         具体如下:
             对一个字,存储时先存放低字节,再存放高字节(即低字节占低地址,
                 高字节占高地址)。字的地址是指其低字节的地址。
             对一个双字,存储时先存放低字,再存放高字(即低字占低地址,高
                 字占高地址)。双字的地址是指其低字的地址。在每个字的内部,
                 同样按低字原则存放。

          注意,无论是字节、字、双字,总体是还是往上长的,所谓倒是指在每个
                字(或双字)的内部是倒的,但字与字(或双字与双字)之间还是
                顺序存放的。
      
         A1:
            bool IsBigendian()
            {
                unsigned short usData = 0x1122;
                unsigned char *pucData = (unsigned char*)&usData;
               
                return (*pucData == 0x22);
            } 
                       
         A2:
            int checkCPU()
            {
                UNION f
                {  
                    int  a;
                   char b;
                }c;
           
                c.a = 1;
           
                return (c.b == 1);
            }

 


二:内存使用
    关键字volatile有什么含意?并给出三个不同的例子。
    一个定义为volatile的变量是说这变量可能会被意想不到地改变,这
    样,编译器就不会去假设这个变量的值了。精确地说就是,优化器在
    用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使
    用保存在寄存器里的备份。下面是volatile变量的几个例子:
    -> 并行设备的硬件寄存器(如:状态寄存器)
    -> 一个中断服务子程序中会访问到的非自动变量(Non-automatic
        variables)
    -> 多线程应用中被几个任务共享的变量

        回答不出这个问题的人是不会被雇佣的。我认为这是区分C程序员
    和嵌入式系统程序员的最基本的问题。搞嵌入式的家伙们经常同硬件、
    中断、RTOS等等打交道,所有这些都要求用到volatile变量。不懂得
    volatile的内容将会带来灾难。
        假设被面试者正确地回答了这是问题(嗯,怀疑是否会是这样),
    我将稍微深究一下,看一下这家伙是不是直正懂得volatile完全的重
    要性。
    ->    一个参数既可以是const还可以是volatile吗?解释为什么。
    ->    一个指针可以是volatile 吗?解释为什么。
    ->    下面的函数有什么错误:
        int square(volatile int *ptr)
        {
            return *ptr * *ptr;
        }
    下面是答案:
    -> 是的。一个例子是只读的状态寄存器。它是volatile因为它可能
        被意想不到地改变。它是const 因为程序不应该试图去修改它。
    -> 是的。尽管这并不很常见。一个例子是当一个中服务子程序修该
        一个指向一个buffer的指针时。
    -> 这段代码有点变态。这段代码的目的是用来返指针*ptr指向值的
        平方,但是,由于*ptr指向一个volatile型参数,编译器将产生
        类似下面的代码:
        int square(volatile int *ptr)
        {
            int a,b;
            a = *ptr;
            b = *ptr;
            return a * b;
        }
        由于*ptr的值可能被意想不到地该变,因此a和b可能是不同的。
        结果,这段代码可能返不是你所期望的平方值!正确的代码如下:
        long square(volatile int *ptr)
        {
            int a;
            a = *ptr;
            return a * a;
        }


三:中断相关
   中断是嵌入式系统中重要的组成部分,这导致了很多编译开发商提供
   一种扩展—让标准C支持中断。具代表事实是,产生了一个新的关键字
   __interrupt。下面的代码就使用了__interrupt关键字去定义了一个
   中断服务子程序(ISR),请评论一下这段代码的。
        __interrupt double compute_area (double radius)
        {
            double area = PI * radius * radius;
            printf("\nArea = %f", area);
            return area;
        }

        这个函数有太多的错误了,以至让人不知从何说起了:
        1: ISR 不能返回一个值。如果你不懂这个,那么你不会被雇
            用的。
        2: ISR 不能传递参数。如果你没有看到这一点,你被雇用的
            机会等同第一项。
        3: 在许多的处理器/编译器中,浮点一般都是不可重入的。有
            些处理器/编译器需要让额处的寄存器入栈,有些处理器/编
            译器就是不允许在ISR中做浮点运算。此外,ISR应该是短而
            有效率的,在ISR中做浮点运算是不明智的。
        4:与第三点一脉相承,printf()经常有重入和性能上的问题。
       
        如果你丢掉了第三和第四点,我不会太为难你的。不用说,如果
        你能得到后两点,那么你的被雇用前景越来越光明了。
       
四:函数调用;
     1:已知,一个函数的地址为0Xa8,定义方式为无参数,如何调用它??       

posted on 2006-01-19 19:35  嵌入专栏  阅读(595)  评论(2编辑  收藏  举报