本帖最后由 仰望星空之云 于 2021-7-10 10:25 编辑
今天给大家讲解一下uboot中的字节对齐操作 很多朋友对uboot中汇编语句中关于字节对齐的代码很疑惑,比如: 上述代码的作用是完成8字节地址对齐,具体是对哪个地址呢?从代码可以看出是要调整SP指针所指向的地址。要想看懂这个代码首先要明白两个知识点: 1、什么叫做8字节地址对齐? 所谓的8字节地址对齐就是这个地址可以被8整除,假设当前SP指针所指向的地址为0X80000013,很明显0x80000013不能被8整除,0X800000013/8=0x80000010余3。所以我们需要将SP进行8字节对齐,其实就是将SP指针调整到一个最近的能被8整除的地址上去。 2、堆栈增长方向 SP指向栈顶的,要调整SP必须要保证SP不能指向已经被占用的栈空间,比如6ULL(Cortex-A7)的堆栈是向下增长的(也就是从高地址到底地址)。离0X80000013最近的两个能被8整除的数据分别是0X80000018和0X80000010,因为6ULL(Cortex-A7)的堆栈是向下增长的,因此SP进行8字节对齐以后只可能是0X80000010。如果堆栈是向上增长的,那么SP进行8字节对齐以后就是0X80000018。 理解了上面2个知识点以后我们再来看一下“bic sp,sp #7”是如何调整SP为8字节对齐的,首先bic指令的作用是位清零,因此: 作用: 将sp所保存的地址,按照#07(0x0111)进行位清零,也就是将sp所保存的地址低3位全部清零。 将0X80000013的低3位进行清零以后不就是0X80000010了吗!不正是我们前面分析的结果吗?方法很简单,你不是不能被8整除吗?那就将你不能被整除(也就是余数)部分抛弃掉就行了啊。大家可能会有疑问,这样做的话0X80000011~0X8000013这3个地址空间就不要了吗?对的!就是不要了! 同理,0X80000011~0X80000017这7个数都不能8整除,这7个地址8字节对齐后的地址都是0X80000010! 最后再延伸一下,如果要做4字节、16字节、64字节……,地址对齐该怎么做呢?方法很简单,: - bic sp,sp #3 //4字节地址对齐
- bic sp,sp #15 //16字节地址对齐
- bic sp,sp #63 //64字节地址对齐
复制代码 核心思想就是将余数给抛弃掉!前提是堆栈增长方向是向下的!
|