ARM函数调用 参数传递

/*环境keil4 + STM32*/
/*函数体和它的汇编代码*/
/*全局变量写入*/
void SetCalStatus1(gUINT8 Par1,gUINT8 Par2)
{	
	gUINT32 CPUStatus = 0x05;
	gUINT8 Temp = 6;

	__nop();
	CalendarStatus = Par1;
	__nop();
	CalendarStatus = Par2;
	__nop();
}
 

0x08000A02 0800      LSRS     r0,r0,#0
//   198: {        
0x08000A04 B510      PUSH     {r4,lr}		/*下面使用了R4压入堆栈,LR返回地址*/
//   199:         gUINT32 CPUStatus = 0x05; 
0x08000A06 2205      MOVS     r2,#0x05		/*赋值CPUStatus*/
//   200:         gUINT8 Temp = 6; 
//   201:  
0x08000A08 2306      MOVS     r3,#0x06		/*赋值Temp*/
//   202:         __nop(); 
0x08000A0A BF00      NOP      
//   203:         CalendarStatus = Par1;					/*316由汇编器计算得出*/
0x08000A0C 4C4F      LDR      r4,[pc,#316]  ; @0x08000B4C	/*加载全局变量CalendarStatus的地址*/
0x08000A0E 7020      STRB     r0,[r4,#0x00]					/*把R0,即参数1,写入CalendarStatus地址处*/
//   204:         __nop(); 
0x08000A10 BF00      NOP      
//   205:         CalendarStatus = Par2; 
0x08000A12 7021      STRB     r1,[r4,#0x00]					/*把R1,即参数1,写入CalendarStatus地址处*/
//   206:         __nop(); 
0x08000A14 BF00      NOP      
//   207: } 
0x08000A16 BD10      POP      {r4,pc}						/*R4和PC出栈*/


/*调用这个函数的C代码和汇编代码*/


	GPIO_ResetBits(BEEP_PORT,BEEP);
	SetCalStatus1(3,4);
	while(1)
	{


		。。。。。。
0x08000A62 483D      LDR      r0,[pc,#244]  ; @0x08000B58
0x08000A64 F001FA51  BL.W     GPIO_ResetBits (0x08001F0A)
//   334:         SetCalStatus1(3,4); 
0x08000A68 2104      MOVS     r1,#0x04		/*加载参数到r1*/
0x08000A6A 2003      MOVS     r0,#0x03		/*加载参数到r0*/
0x08000A6C F7FFFFCA  BL.W     SetCalStatus1 (0x08000A04)	/*调用函数*/
//   335:         while(1) 
//   336:         {        
		。。。。。。




可以看到修改全局变量的值需要两条指令。
0x08000A0C 4C4F      LDR      r4,[pc,#316]  ; @0x08000B4C	/*加载全局变量CalendarStatus的地址*/
0x08000A0E 7020      STRB     r0,[r4,#0x00]					/*把R0,即参数1,写入CalendarStatus地址处*/

在RTOS中如果在不关中断保护的情况下,修改全局变量的值,有可能在这两句之间产生任务切换。

/*全局变量读取*/
gUINT8 GetCalStatus1()
{	
	gUINT8 Temp;

	__nop();
	Temp = CalendarStatus;
	__nop();

	return Temp;
}

//   201:         __nop(); 
0x08000A04 BF00      NOP      
//   202:         Temp = CalendarStatus; 
0x08000A06 4955      LDR      r1,[pc,#340]  ; @0x08000B5C	/*加载全局变量的地址*/
0x08000A08 7808      LDRB     r0,[r1,#0x00]					/*载入全局变量值*/
//   203:         __nop(); 
//   204:  
//   205:         return Temp; 
0x08000A0A BF00      NOP      
   206: } 

可以看到读取全局变量的值也需要需要两条指令,如果在两条指令之间切换任务,
在任务切换回来可能就会出现,读出的是旧值。


 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值