【每日一题】(D0801)写一个宏返回结构体的地址


一、单选题

1、(单选)关于 Cortex-M 描述错误的是()

A Cortex-M 系列支持 16 位和 32 位的 Thumb 指令集
B Cortex-M 上下文切换时可以使用 MSP 主栈
C 复位中断和 NMI 中断不可以被屏蔽
D LDR R0 = 0x12345678,汇编器会将 R0 直接赋值为 0x12345678


2、(单选)关于外设总线描述错误的是()

A IIC 主从机通讯有两根线,SCL(时钟线) 和 SDA(数据线)
B IIC 可以进行全双工通信
C IIC 和多从机通讯时通过地址选择从机
D IIC 属于同步通信


3、线程同步常用到的方式不包含()

A 全局变量
B 互斥量
C 信号量
D 时间标志组


4、linux 内核主要由 5 个子系统组成,下面选项不属于这 5 个子系统的是()

A 进程调度
B 内存管理
C 虚拟文件系统
D 浏览器程序


二、多选题

1、(多选)下列关于 arm 的 Cortex-m 内核寄存器,下面说法正确的是()

A 对于通用寄存器,arm内核在进入中断时只会将现场 R0~R3寄存器压入栈保护
B VTOR寄存器可以修改中断向量表入口地址
C PRIMASK 寄存器可以用来屏蔽除 NMI 中断和 hardfault 中断之外的所有中断
D R13为栈指针寄存器,其中 MSP 寄存器是上电之后硬件自动写入


2、(多选) 对于嵌入式实时操作系统 RTOS,以下说法正确的是()

A PTOS 相应中断时,中断函数中的局部变量,保存在进入中断前的任务栈中
B 任务切换时需要进入临界区,保证切换过程中不被打断
C 任务调度时间片应设置尽可能小,以保证高优先级任务能够更快响应,不会带来额外的计算开销
D 对于多个任务均需要使用的共享资源,一般使用互斥量来保护


3、(多选)下面说法正确的是()

A 使用 inline 声明函数,编译不报错的情况下表明该函数已经被内联
B 设置栈空间大小影响编译出的 bin 固件大小
C 编译固件时使用 00 优化表示不做任何优化
D C程序编译一般包含预处理、编译、汇编、链接四个环节


4、(多选)关于外设资源,以下说法正确的是()

A SPI 总线有 4 种模式
B ADC总采样周期 = 保持时间 + 转换时间
C PWM(或定时器)不同计数模式下,设置同一个比较值产生的占空比是相同的
D UART 通信主机和从机可以设置不同波特率


5、(多选)下列关于处理器的说法中,正确的有哪些()

A 通常用 DMIPS 来衡量处理器的浮点计算能力
B ARMv8是 ARM 指的处理令集的支持 64 位指令集的处理器架构
C 根据IEEE 754 标准,单精度浮点数的指数域(exponent)有 8 位
D NEON 是 intel 公司推出的单指令多数据扩展架构技术


6、(多选)以下哪些不是实时操作系统()

A Windows10
B Ubuntu 20.04
C freeRTOS
D Android


7、(多选)下列关于 git 说法正确的是()

A git add 命令会自动忽略 .gitignore 文件中描述的文件
B 通过 git reset 命令可以允许操作者撤销当前全部的修改,恢复代码文件到上个 commit 时候的状态
C 使用 git rm 命令会真的删除文件,且=无法通过 git 的历史快照找回文件
D 使用 git cherry-pick 命令时,如果存在冲突,git 会首先尝试自己解决冲突,如果无法解决则会提示操作者自己解决。


8、(多选)以下关于操作系统调度说法,正确的是()

A 使用锁会降低多核 cpu 调度的并行性,代码设计中应该尽量减少锁的使用
B 相对于 IO 密集型任务, CPU 密集型任务的调度优先级应该尽可能设置高些,以便获得更多的 CPU资源
C 出现调度优先级反转是因为调度器改变了任务的优先级
D 支持优先级继承的调度器会动态改变任务的优先级


三、问答题

1、已知结构体某个成员的地址,写一个宏返回这个结构体的地址。

答:假设存在一个虚拟地址 0,将该地址强制转换成为该结构体指针类型(struct stru_name*)0。那么地址 0 开始到 sizeof(stru_name) - 1 长度的内存区域就可以视为一个结构体的内存。这样结构体中任何一个元素都可以通过对该结构体指针解引用得到。由于该结构体的起始地址为 0, 因此任何一个成员的地址应该等于其相对于结构体起始地址的偏移,这也就是计算偏移量的方法:(unsigned long)&((struct stru_name*)0) -> element

看看下面这段代码:

#include <stdio.h>
#define STRUCT_OFFSET(stru_name, element) (unsigned long)&((struct stru_name*)0)->element
struct stru_addr 
{
    int a;
    char b;
    int d;
    char c;

};

int main(void)
{
    struct stru_addr s;
    printf("start addr of s = %x\n", &s.a);
    
    unsigned long offset = STRUCT_OFFSET(stru_addr, c);

    printf("c_addr = %x, offset = %u\n", &s.c, offset);
    printf("start addr of s caculated from c addr: %x\n", (char *)&s.c - offset);
    return 0;
}

运行结果:

start addr of s = bf81b820
c_addr = bf81b82c, offset = 12
start addr of s caculated from c addr: bf81b820

2、一个函数中定义一个数组,大小为 1 K byte,如果它被错误的写入了 4 K byte 的数据,是否会导致栈溢出?如果会,还有什么样的情形会导致栈溢出?如果不会导致栈溢出,会导致什么问题?

答:



版权声明:本文为Sunnyside_原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。