对LED点灯实验的C与汇编的深入分析,提及到volatile

C与汇编点灯实验分析

查看点灯实验的反汇编代码,如下图所示:
在这里插入图片描述

下面是 C 代码,main 函数:

int main()
{
	unsigned int *pReg;
	
	/* 使能GPIOB */
	pReg = (unsigned int *)(0x40021000 + 0x18);
	*pReg |= (1<<3);
	
	/* 设置GPIOB0为输出引脚 */
	pReg = (unsigned int *)(0x40010C00 + 0x00);
	*pReg |= (1<<0);

	pReg = (unsigned int *)(0x40010C00 + 0x0C);
	
	while (1)
	{
		/* 设置GPIOB0输出1 */
		*pReg |= (1<<0);
		
		delay(100000);

		/* 设置GPIOB0输出0 */
		*pReg &= ~(1<<0);
		
		delay(100000);		
	}
	
	return 0;
}

查看有无 volatile 对 delay 函数的影响:

  • 无 volatile,编译器自动优化了,为了提升速度,不需要将变量存入栈中,它直接存放在 CPU 的寄存器里:
void delay(int d)	//参数的值已经存在r0里
{
	while(d--);
}
i.delay
delay
    0x08000138:    bf00        ..      NOP      
    0x0800013a:    1e01        ..      SUBS     r1,r0,#0			;这个递减会影响到程序状态寄存器,不过这个不会改变变量值
    0x0800013c:    f1a00001    ....    SUB      r0,r0,#1			;这个指令才会让r0-1
    0x08000140:    d1fb        ..      BNE      0x800013a 		;如果不等于0就跳到0x0800013a地址继续执行delay函数
    0x08000142:    4770        pG      BX       lr					;0之后就跳转到lr寄存器
  • 有 volatile,再搞个返回值,目的是清楚的看到函数结束后返回哪里。volatile 的作用是提醒编译器不需要优化我的代码,变量该保存到栈中就保存到栈中,这样,代码的可靠性就增加了,但是效率下降:
int delay(volatile int d)
{
	while(d--);
	return 0x55;
}
i.delay
delay
    0x08000138:    b501        ..      PUSH     {r0,lr}		;PUSH就是保存到栈里面去,将r0和lr的值保存到栈里
    0x0800013a:    bf00        ..      NOP      	
    0x0800013c:    9800        ..      LDR      r0,[sp,#0]	;再将栈里r0原本保存的值100000读到r0里
    0x0800013e:    1e41        A.      SUBS     r1,r0,#1	;r1 = r0 - 1,并影响程序状态寄存器
    0x08000140:    9100        ..      STR      r1,[sp,#0]	;再把r1的值放入栈中,也就是刚刚存放的10000,经过-1操作后变成9999
    0x08000142:    2800        .(      CMP      r0,#0		;将r0的值与0比较
    0x08000144:    d1fa        ..      BNE      0x800013c	;如果不为0,就跳转到0x0800013c地址上继续自减
    0x08000146:    2055        U       MOVS     r0,#0x55	;如果为0,就将0x55放到r0寄存器
    0x08000148:    bd08        ..      POP      {r3,pc}		;从栈中把之前的值恢复出来,lr的地址赋值给pc,delay函数结束后就返回lr保存的地址
    0x0800014a:    0000        ..      MOVS     r0,r0
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值