1、有如下CAT_s结构体定义,回答:
struct CAT_s{
int ld;
char Color;
unsigned short Age;
char *Name;
void(*Jump)(void);
}Garfield;
1)在一台64位的机器上,使用32位编译,Garfield 变量占用多少内存空间?64位编译又是如何?(总分5分)
答案:
考点—>字节对齐
32位系统以4字节对齐,该结构体占16个字节;64位系统以8字节对齐,该结构体占24个字节。结构体里面不同类型参数的排序不同会影响结构体的大小。
2) 使用32位编译情况下,给出一种判断所使用机器大小端的方法。(总分5分)
判断方法:利用union结构体的从低地址开始存,且同一时间内只有一个成员占有内存的特性。大端储存符合阅读习惯。
#include
int Check_sys()
{
#数据高位是c,低位是i
union Un
{
char c;
int i;
}un;
un.i = 1;
return un.c;
}
int main()
{
int ret=Check_sys();
if (1 == ret) printf("当前模式为小端存储\n");
else printf("当前模式为大端存储\n");
return 0;
}
2、描述下面XXX 这个宏的作用。(总分10分)
#define offsetof(TYPE,MEMBER)((size_t)&((TYPE*)0)->MEMBER)
#define XXX(ptr,type,member({\
const typeof(((type*)0)->member)*__mptr=(ptr);\
(type*)(char*)__mptr – offsetof(type,member));})
答案:
#define offsetof(TYPE,MEMBER)((size_t)&((TYPE*)0)->MEMBER)
#define XXX(ptr,type,member) ({\
const typeof(((type*)0)->member) *__mptr=(ptr);\
(type*)((char*)__mptr – offsetof(type,member));})
3、简述C 函数:1) 参数如何传递(__cdecl调用方式);2) 返回值如何传递;3) 调用后如何 返回到调用前的下一条指令执行。(总分10分)
答案:
1)
__cdecl:C Declaration的缩写,C的默认调用方法。
__stdcall:StandardCall的缩写,C++的默认调用方式。
2)
设返回值大小为M字节:
3)C语言通过硬件栈保存函数的返回地址,被调用函数将返回地址出栈到程序计数器PC中,以返回到调用点。
4、在一个多任务嵌入式系统中,有一个CPU 可直接寻址的32位寄存器REGn ,地址为 0x1F000010,编写一个安全的函数,将寄存器REGn 的指定位反转(要求保持其他bit 的值不变)。(总分10分)
答案:
异或运算。
void bit_reverse(uint32_t nbit)
{
*((volatile unsigned int *)0x1F000010) ^= (0x01 << nbit);
}
5、有10000个正整数,每个数的取值范围均在1到1000之间,变成找出从小到大排在第 3400(从0开始算起)的那个数,将此数的值返回,要求不使用排序实现。(总分10分)
答案:计算不同整数值对应的整数个数
#include
using namespace std;
#define TOTAL 10000
#define RANGE 1000
#define REQUIRED 3400
int main()
{
int number[TOTAL] = { 0 };
int count[RANGE] = { 0 };
int i, sum = 0;
for (i = 0; i < 10000; i++) {
number[i] = (rand() % 1000) + 1; /*产生10000个1-1000之间的随机数*/
}
for (i = 0; i < 10000; i++) {
count[number[i] - 1]++; /*计算10000个整数出现次数*/
}
for (i = 0; i < 1000; i++) {
sum += count[i];
if (sum >= REQUIRED + 1) {
cout << i + 1 << endl;
break;
}
}
return 0;
}
简述处理器中断处理的过程(中断向量、中断保护现场、中断嵌套、中断返回等)。(总 分10分)
答案:
中断向量:
中断服务程序的入口地址
中断嵌套:
中断系统正在执行一个中断服务时,有另一个优先级更高的中断提出中断请求,这时会暂时终止当前正在执行的级别较低的中断源的服务程序,去处理级别更高的中断源,待处理完毕,再返回到被中断了的中断服务程序继续执行
保护现场:主程序和中断服务子程序都要使用CPU内部寄存器等资源,为使中断处理程序不破坏主程序中寄存器的内容,应先将断点处各寄存器的内容压入堆栈保护起来,再进入的中断中断返回过程如下:首先恢复原保留寄存器的内容和标志位的状态,这称为恢复现场
中断返回:
由用户编程完成。然后,再加返回指令RETI,RETI指令的功能是恢复PC值,使CPU返回断点,这称为恢复断点。恢复现场和断点后,CPU将继续执行原主程序,中断响应过程到此为止处理。现场保护是由用户使用PUSH指令来实现的。
恢复现场:
当中断处理完毕后,用户通过POP指令将保存在堆栈中的各个寄存器的内容弹出,即恢复主程序断点处寄存器的原值。
中断服务:
中断服务是执行中断的主体部分,不同的中断请求,有各自不同的中断服务内容,需要根据中断源所要完成的功能,事先编写相应的中断服务子程序存入内存,等待中断请求响应后调用执行
简述处理器在读内存的过程中,CPU 核、cache 、MMU 如何协同工作?画出CPU 核、 cache 、MMU 、内存之间的关系示意图加以说明(可以以你熟悉的处理器为例)。(总分10分)
请说明总线接口USRT 、I2C 、USB 的异同点(串/并、速度、全/半双工、总线拓扑等)。 (总分5分)
列举你所知道的linux 内核态和用户态之间的通信方式并给出你认为效率最高的方式, 说明理由。(总分5分)
有一个使用UART 进行通信的子系统X ,其中UART0进行数据包接收和回复,UART1进行数据包转发。子系统X 的通信模块职责是从UART0接收数据包,如果为本地数据包(receiver 为子系统X ),则解析数据包中的命令码(2字节)和数据域(0~128字节),根据命令码调用内部的处理程序,并将处理结果通过UART0回复给发送端,如果非本地数据包,则通过UART1转发。
如果由你来设计子系统X 的通信模块: