笔试FAQ

1.冯~诺依曼结构和哈佛结构的区别?各有什么特点?

  • 区别:哈佛结构的数据存储器和指令存储器是分开的,数据存储器和指令存储器 与 CPU 分别有一条总线相连,二者互不干扰。CPU先到指令存储器中读取指令内容,得到数据地址,再到数据存储器中读取数据,利用数据进行下一步操作;冯~诺依曼结构中数据存储和指令存储在同一个存储器中。
  • 特点:哈佛结构中有一个数据存储器,一个指令存储器,一个运算器(ALU),一对I/O。由于哈佛结构中的数据和指令分开存储,互不影响,所以取指和取操作数可以同时进行,在执行时可以预先读取下一条指令,运行效率较高,数据的位数和指令的位数可以不同;冯诺依曼结构要求必须有一个存储器、一个运算器、一个控制器、一对I/O。而且由于数据和指令存储在同一个存储器中,它们的位数是一样的。

哈佛结构(主要用于 ARM )
哈佛结构
冯~诺依曼结构(主要用于 PC)
在这里插入图片描述

2、简述 Cortex M3 和 Cortex M4 内核中的寄存器组 R0 ~ R15 的作用,尽量详细 + 举例

在这里插入图片描述

  • R0 ~ R12 是通用寄存器,初始值是未知的。前 8 位寄存器(R0 ~ R7)称为低位寄存器,R8 ~ R12 称为高位寄存器。由于存储指令集的空间有限,16 位指令只能访问低位存储器,高位存储器只能被 32 位指令和少部分的 16 位指令(如 MOV)访问。
  • R13 是堆栈指针(SP),被用来访问栈空间,它有两种形态,一种是主堆栈指针(简称为 MSP),是 R13 的默认形态,另一种是进程堆栈指针(简称为PSP),这两种形态在普通程序中只能显示一种。如果不是在嵌入式操作系统中,就没有必要用进程堆栈指针,完全可以用主堆栈指针实现栈空间的访问;如果是在嵌入式操作系统,由于栈空间被操作系统内核和进程任务分割而变得不连续,所以必须使用进程堆栈指针。
  • R14 是连接寄存器(LR),调用一个函数或子程序返回的地址如果存放在内存,程序要访问该地址时需要去内存中取,这个过程至少需要 3 个指令周期,比较耗时间;而如果把返回的地址放到 R14 寄存器中,则程序需要该地址时直接从寄存器中取即可,大大提高程序的运行效率。
  • R15 是程序计数寄存器(PC)指向当前程序的地址。如果修改它的值,就能改变程序的执行流。

3.ARM 指令集 、Thumb 指令集、Thumb2 指令集的区别

  • ARM 指令集:指令都是 32 位的,单条指令承载的信息多,因此完成任务所需的指令少,程序的运行速度快,但因为单条指令承载的内容多,所以占用的内存空间大。
  • Thumb 指令集:指令都是 16 位的,单条指令承载的信息少,因此完成任务所需要的指令多,运行速度慢,但占用的内存少。
  • Thumb2 指令集:将前两者有机结合在一起,该使用 32 位指令的时候使用 32 位,提高运行速度;该使用 16 位的时候使用 16 位,节省内存空间。

4、volatile 的作用与应用场景

  • 作用:一个共享变量(类的成员变量、类的静态成员变量)被volatile修饰之后,保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的;禁止指令重排序,在一定程度上保证了有序性,即在执行到volatile变量时,前面的程序可以保证已经执行完毕。
  • 应用场景:状态标记量

5、写一个函数,用冒泡排序法对整型数组进行升序排序

#include <iostream>
extern "C"{
    #include <stdlib.h>
}
using namespace std;

//冒泡排序函数
int* bubbles(int num, int* a){
    for(int i = 0; i < num; i++)    //  插入数据
        cin >> a[i];
    
    int tmp = 0;
    for (int i = 0; i < num; i++)
    {
        for (int j = 0; j < num - i - 1; j++)
        {
            if(a[j] < a[j+1]){
                tmp = a[j];
                a[j] = a[j+1];
                a[j+1] = tmp;
            }
        }
    }
    return a;
}

int main(int argc, char const *argv[])
{
    //初始化数组的大小
    int num = 0;
    cin >> num;
    int *arr = (int *)malloc(sizeof(int) * num);
    arr = bubbles(num, arr);
    for (int i = 0; i < num; i++)
        cout << arr[i] << "  ";
    
    //释放堆空间
    free(arr);
    return 0;
}

6、请简述 LSB 和 MSB 的区别以及如何判断大小端模式

  • LSB:Least Significant Bit,最低有效位,通常位于二进制中的最右端
  • MSB:Most Significant Bit,最高有效位,用于表示数的正负,0 表示正数,1 表示负数,通常位于二进制的最左端
  • 小端模式:数据的低位存放在低地址中,高位存放在高地址中
  • 大端模式:数据的高位存放在低地址中,低位存放在高地址中
  • 区分大小端模式的方法:数据类型转换法,联合体法
    1. 数据类型转换法
#include <iostream>
using namespace std;

int main(int argc, char const *argv[])
{
    int a = 0x12345678;
    short b = (short)a;
    cout << hex << b << endl;
    return 0;
}

输出的结果:
在这里插入图片描述
输出的是 5678,说明电脑的存储方式是小端存储

    1. 联合体法(联合体是从低地址开始存放数据,里面的数据共享一份内存。将一个 4位 的数据赋值给一个 2 位的变量,观察变量存储的值,即可知道数据的存储方式)
union aaa{
    int a = 0x12345678;
    short b;
};

int main(int argc, char const *argv[])
{
    union aaa un;
    cout << "un.a = " << hex << un.a << endl;
    cout << "un.b = " << hex << un.b << endl;
    return 0;
}

我的运行结果:
在这里插入图片描述

7、TTL、RS232、RS485的区别

  • TTL(晶体管-晶体管逻辑电路)是正逻辑电路,逻辑 1 表示 +5V, 逻辑 0 表示 0V ,采用异步全双工通信协议
  • RS232 是负逻辑电路,逻辑 1 表示 -3V ~ -15V,逻辑 0 表示 +3V ~ +15V ,采用异步全双工通信协议
  • RS485 为了长距离传输采用差分方式传输,传输的是差分信号,抗干扰能力比 RS232 强很多,稳定性更强,逻辑 1 表示 两线压差为 +(2 ~ 6)V ,逻辑 0 表示 两线压差 -(2 ~ 6)V,采用半双工通信协议

8、static的作用

  • 1、隐藏。所有未加 static 前缀的全局变量和函数都具有全局可见性,其它的源文件也能访问。如果加了 static,就会对其它源文件隐藏。利用这一特性可以在不同的文件中定义同名函数和同名变量,而不必担心命名冲突。
  • 2、保持变量内容的持久。static 变量存储在静态存储区,和程序共生死。
  • 3、 默认初始化为 0。在静态存储区,内存中所有的字节默认值都是 0x00,某些时候这一特点可以减少程序员的工作量。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值