__align(4)的问题

Q:

__align(4)  这是MDK中的一种语法?作用什么;;__align(4) u8 mem1base[MEM1_MAX_SIZE];这条语句的作用是定义MEM1_MAX_SIZE个u8类型的数组,使用4字节对齐的方式吗?

A:

用align修饰数组后,可以去掉packed关键字了. 

ARM下的对齐处理  
from DUI0067D_ADS1_2_CompLib 

3.13 type  qulifiers 

有部分摘自ARM编译器文档对齐部分 

对齐的使用: 
1.__align(num) 
   这个用于修改最高级别对象的字节边界。在汇编中使用LDRD或者STRD时 
   就要用到此命令__align(8)进行修饰限制。来保证数据对象是相应对齐。 
   这个修饰对象的命令最大是8个字节限制,可以让2字节的对象进行4字节 
   对齐,但是不能让4字节的对象2字节对齐。 
   __align是存储类修改,他只修饰最高级类型对象不能用于结构或者函数对象。 
    
2.__packed  
  __packed是进行一字节对齐 
  1.不能对packed的对象进行对齐 
  2.所有对象的读写访问都进行非对齐访问 
  3.float及包含float的结构联合及未用__packed的对象将不能字节对齐 
  4.__packed对局部整形变量无影响 
  5.强制由unpacked对象向packed对象转化是未定义,整形指针可以合法定 
  义为packed。 
     __packed int* p;  //__packed int 则没有意义 
  6.对齐或非对齐读写访问带来问题 
  __packed struct STRUCT_TEST 

  char a; 
  int b; 
  char c; 
}  ;    //定义如下结构此时b的起始地址一定是不对齐的 
         //在栈中访问b可能有问题,因为栈上数据肯定是对齐访问[from CL] 
//将下面变量定义成全局静态不在栈上  
static char* p; 
static struct STRUCT_TEST a; 
void Main() 

__packed int* q;  //此时定义成__packed来修饰当前q指向为非对齐的数据地址下面的访问则可以 

p = (char*)&a;           
q = (int*)(p+1);       

*q = 0x87654321;  
/*    
得到赋值的汇编指令很清楚 
ldr      r5,0x20001590 ; = #0x12345678 
[0xe1a00005]   mov      r0,r5 
[0xeb0000b0]   bl       __rt_uwrite4  //在此处调用一个写4byte的操作函数  
       
[0xe5c10000]   strb     r0,[r1,#0]   //函数进行4次strb操作然后返回保证了数据正确的访问 
[0xe1a02420]   mov      r2,r0,lsr #8 
[0xe5c12001]   strb     r2,[r1,#1] 
[0xe1a02820]   mov      r2,r0,lsr #16 
[0xe5c12002]   strb     r2,[r1,#2] 
[0xe1a02c20]   mov      r2,r0,lsr #24 
[0xe5c12003]   strb     r2,[r1,#3] 
[0xe1a0f00e]   mov      pc,r14 
*/ 

/* 
如果q没有加__packed修饰则汇编出来指令是这样直接会导致奇地址处访问失败 
[0xe59f2018]   ldr      r2,0x20001594 ; = #0x87654321 
[0xe5812000]   str      r2,[r1,#0] 
*/ 

//这样可以很清楚的看到非对齐访问是如何产生错误的 
//以及如何消除非对齐访问带来问题 
//也可以看到非对齐访问和对齐访问的指令差异导致效率问题 
}

你可能感兴趣的:(嵌入式)