• 转载:嵌入式C语言面试题(二)


    BSS段

      是“Block Started by Symbol”的缩写,意为“以符号开始的块”。
     
      BSS是Unix链接器产生的未初始化数据段。其他的段分别是包含程序代码的“text”段包含已初始化数据的“data”段BSS段的变量只有名称和大小却没有值。此名后来被许多文件格式使用,包括PE。“以符号开始的块”指的是编译器处理未初始化数据的地方。BSS节不包含任何数据,只是简单的维护开始和结束的地址,以便内存区能在运行时被有效地清零。BSS节在应用程序的二进制映象文件中并不存在。
     
      在采用段式内存管理的架构中(比如intel的80x86系统),bss段(Block Started by Symbol segment)通常是指用来存放程序中未初始化的全局变量的一块内存区域,一般在初始化时bss 段部分将会清零。bss段属于静态内存分配,即程序一开始就将其清零了。
     
      比如,在C语言之类的程序编译完成之后,已初始化的全局变量保存在.data 段中,未初始化的或初始化为0全局变量保存在.bss 段中。
     
      text和data段都在可执行文件中(在嵌入式系统里一般是固化在镜像文件中),由系统从可执行文件中加载;而bss段不在可执行文件中,由系统初始化
     
    1 读程序段,回答问题
    int main(int argc,char *argv[])
    {
    int c=9,d=0;
    c=c++%5;
    d=c;
    printf("d=%d\n",d);
    return 0;
    }
    a) 写出程序输出
    b) 在一个可移植的系统中这种表达式是否存在风险?why?
      答案:5,存在风险,因为c=c++%5;这个表达式对c有两次修改,行为未定义,c的值不确定。

     2,
    #include "stdio.h"
    int a=0;
    int b;
    static char c;
    int main(int argc,char *argv[])
    {
    char d=4;
    static short e;
    a++;
    b=100;
    c=(char)++a;
    e=(++d)++;
    printf("a=%d, b=%d, c=%d, d= %d, e=%d",a,b,c,d,e);
    return 0;
    }
    a) 写出程序输出
    b) 编译器如果安排各个变量(a,b,c,d)在内存中的布局(eg. stack,heap,data section,bss section),最好用图形方式描述。
    答案:
     int a=0; // data section
      int b;   // data section
      static char c; // BSS
      int main(int argc,char *argv[])
      {
        char d=4;         // stack
        static short e;   // BSS
        a++;
        b=100;
        c=(char)++a;
        e=(++d)++;
        printf("a=%d, b=%d, c=%d, d= %d, e=%d",a,b,c,d,e);
        return 0;
      }
      a=2,b=100,c=2,d=6,e=5 
    注意:预备知识—程序的内存分配 
    一个由C/C++编译的程序占用的内存分为以下几个部分 
    1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。 
    2、堆区(heap) — 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表,呵呵。
    3、全局区(静态区)(static)—,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。 - 程序结束后有系统释放 
    4、文字常量区 —常量字符串就是放在这里的。 程序结束后由系统释放 
    5、程序代码区—存放函数体的二进制代码。

     
     
     
    3 嵌入式系统相关问题
    a) 对于整形变量A=0x12345678,请画出在little endian及big endian的方式下在内存中是如何存储的。
    答案:a) 0x12345678
     little endian        big endian 刚好反过来
      高地址--〉 0x12      低地址--〉 0x12
                 0x34                 0x34
                 0x56                 0x56
      低地址--〉 0x78      高地址--〉 0x78
     
    b) 在ARM系统中,函数调用的时候,参数是通过哪种方式传递的?
    答案:b)参数<=4时候,通过R0~R3传递,>4的通过压栈方式传递

    c) 中断(interrupt,如键盘中断)与异常(exception,如除零异常)有何区别?
     
    答案:c)   异常:在产生时必须考虑与处理器的时钟同步,实践上,异常也称为同步中断。在处理器执行到由于编程失误而导致的错误指令时,或者在执行期间出现特殊情况(如缺页),必须靠内核处理的时候,处理器就会产生一个异常
    所谓中断应该是指外部硬件产生的一个电信号,从cpu的中断引脚进入,打断cpu当前的运行;
    所谓异常,是指软件运行中发生了一些必须作出处理的事件,cpu自动产生一个陷入来打断当前运行,转入异常处理流程。
    4 优先级反转问题在嵌入式系统中是一中严重的问题,必须给与足够重视。
    a) 首先请解释优先级反转问题
    b) 很多RTOS提供优先级继承策略(Priority inheritance)和优先级天花板策略(Priority ceilings)用来解决优先级反转问题,请讨论这两种策略。 
    答案:高优先级任务需要等待低优先级任务释放资源,而低优先级任务又正在等待中等优先级任务的现象叫做优先级反转
      优先级继承策略(Priority inheritance):继承现有被阻塞任务的最高优先级作为其优先级,任务退出临界区,恢
    复初始优先级。
      优先级天花板策略(Priority ceilings):控制访问临界资源的信号量的优先级天花板。
      优先级继承策略对任务执行流程的影响相对教小,因为只有当高优先级任务申请已被低优先级任务占有的临界资源
    这一事实发生时,才抬升低优先级任务的优先
  • 相关阅读:
    localStorage保存账号密码
    作品第二课----简易年历
    作品第二课----滚动列表
    自己遇到的冒泡事件
    Oct 20th-绿叶学习网站总结
    Sep 30th-JavaScript的数组方法总结
    Sep 8th -css sprite
    前端知识体系【转】
    July 27th
    第一节 简单的jsp实例
  • 原文地址:https://www.cnblogs.com/loopever/p/2732707.html
Copyright © 2020-2023  润新知