缘起

最近需要在soc系统内做协处理器,加速AES加密运算,寄存器一次读取32bit,AES一次处理128bit,因此在数据拼接的时候,需要考虑大小端的问题,特来记录一番。

一、什么是大小端

大小端的问题发生在寄存器内存间传递数据,这点非常重要,很多地方简单地说是数据存储方式,其实不准确。追根溯源,大小端问题是在设计loadstore指令的时候考虑的,因此本质是寄存器和内存交互的问题,其他地方不会发生。

比如c语言里定义一个变量int a=ox1234,那么查看在线汇编平台的对应汇编代码:

# 给2号寄存器赋值0x1234
li          $2,4660           # 0x1234
# 保存到fp寄存器数值+8的地址,假设为0x1000
sw          $2,8($fp)

假设起始地址是0x1000,那么对小端硬件,高位保存高地址,低位保存低地址:

地址 0x1000 0x1001 0x1002 0x1003
数据 0x34 0x12 00 00

对大端硬件,低位保存高地址,高位保存低地址:

地址 0x1000 0x1001 0x1002 0x1003
数据 00 00 0x12 0x34

我们用的x86cpu是小端,还有riscv也是。PowerPC、MIPS是大端。ARM可以切换。

二、大小端各有什么优势呢?

1.小端优势

做强制类型转换时,不需要调整字节内容。c在线工具

#include 
int main()
{
   int a=0x35;
   char c = (char)a;
   printf("%c",c);   
   return 0;
}

考虑上面的代码,强制转换int类型为char,如果是小端

地址 0x1000 0x1001 0x1002 0x1003
数据 0x35 00 00 00

a的指针指向低地址,对应0x35,只需要直接截取给c。

如果是大端:

地址 0x1000 0x1001 0x1002 0x1003
数据 00 00 00 0x35

还要考虑类型int的长度4,才能找到对应的数据。

2. 大端优势

大端高位在低地址,因此指针的位置就在高位,能够直接判断正负号。

也正是这个优势,大端被用于网络协议传输:

发送端的顺序是低地址到高地址,接收端希望先到达的是高位还是低位数据?网络传输中不可避免有数据比较,因此先接收高位数据能够边接收边比较,效率更高。因此高位数据先来,保存在低地址。这就是大端的优势。

三、如何测试是否问大小端?

下面提供了两种方法:

#include 
#include 
union node
{
     unsigned int m;
     char c;
};
int main()
{
     //1.联合法
     union node data;
     data.m = 0x12345678;
     printf("%x\n",data.c);//78为小端,12为大端
     //2.指针法
     short a = 0x1234;
     char b = *(char*)&a;
     if(0x12 == b){
         printf("big\n");
     }
     else{
    	 printf("little\n");
     }
     return 0;
}

四、AES项目中的问题

项目中定义的密钥字符串: key="9876543210123456"

希望上进入AES的128位为: aes_key[127:0]=0x39 0x38 0x37 0x36...0x35 0x36

1. 小端设备:

内存中key的9保存在最低位,寄存器r1第一次加载的数据为: r1[31:0]=0x36 0x37 0x38 0x39(低地址在低位) 第二次加载的数据为: r2[31:0]=0x32 0x33 0x34 0x35(低地址在低位)

如果直接拼接的话,必然达不到aes_key的输入要求,需要再做交叉分线处理。

2.大端设备

内存中key的9也保存在最低位,寄存器r1第一次加载的数据为: r1[31:0]=0x39 0x38 0x37 0x36(低地址在高位) 第二次加载的数据为: r2[31:0]=0x35 0x34 0x33 0x32(低地址在高位)

因此先加载的地址放到aes_key的高位,可以满足所需要的排序。

这样硬件加速器对平台的大小端,还需要有一个判断操作。

但为什么纯c代码在两个平台都能跑,软件上却没有大小端的判断呢? 因为c代码里都是单字节操作,没有内存和寄存器间大于1byte的加载并计算再存储的问题。

标签: 软硬件协同, 大小端

已有 2 条评论

  1. wufangkai wufangkai

    总结这一篇需要多久时间

  2. fallenangel fallenangel

    写的过程不久,debug和找资料的过程得看运气。这种bug一般两三天吧

添加新评论