在单片机开发中一些值得重视bug

注意 : 以下是在常见开发工具 keil 中运行的结果.

1.下面的代码输出的a是多少 ?

void test0(void)
{
	int a = 5;
	int arr[4] = { 0 };
    a++;
	arr[5] = 10;
    printf("a = %d\r\n", a);
}

int main()
{
	test0();
	while(1) { }
    return 0;
}

答案:10.

2.如果运行这段代码会发生什么 ?

void test0(void)
{
	int index = 7;
	int arr[5] = { 0 };
	printf("test1\r\n");
	*((short*)&arr[index])= 0x101;
}

int main()
{
	test0();
	while(1) { }
    return 0;
}

答案:会一直输出test1.

3.如果运行这段代码会发生什么 ?

void test1(void)
{
	int index = 7;
	int arr[5] = { 0 };
	printf("test1\r\n");
	arr[index] = (int)test2;
}

void test2(void)
{
	int index = 7;
	int arr[5] = { 0 };
	printf("test2\r\n");
	arr[index] = (int)test1;
}

int main()
{
	test1();
	while(1) { }
    return 0;
}

答案:会一直交替输出test1 test2.

如果你知道为什么? 那么恭喜你对栈的理解很达标, 如果不理解没关系, 我们接下来就来分析一下为什么.

我们知道当C语言调用一个函数时候会进行会将lr寄存器压入栈, 而lr储存的是该函数下一行的地址,也就是函数的返回地址,对于第一题我们可以观察出函数栈:

也就是说arr[5]对应地址其实是a的地址,将arr[5]赋值为10, 自然a之前的值也被覆盖看了.

对于后面两题也就显而易见, 将lr改了,自然函数的返回地址也就改了.

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值