打印

C语言中对堆栈的迷惑

[复制链接]
4195|12
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
sw008|  楼主 | 2011-11-7 20:40 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
51单片机的堆栈SP默认指向07F地址,正好是第二页寄存器的开头。
问题是:C语言中堆栈,书中是说在函数调用的时候,自动把函数入口地址压栈。如果中断程序中的using也设为1,正好与堆栈共用同一个地区了。但在反汇编码中看,调用其它函数时,根本没有压栈过程。似乎函数的调用是直接进行固定地址的跳转,不需要事先用压栈来保存被调函数的入口地址,也不知是不是。

堆栈与中断的using设为1,共用同一个地区,会不会有可能造成混乱错误啊?

相关帖子

沙发
ycz9999| | 2011-11-7 21:44 | 只看该作者
记得以前看到过下面这个文档  也是讲述的这个问题

keil中关键字using与寄存器.pdf

174.42 KB

使用特权

评论回复
板凳
ningling_21| | 2011-11-7 22:13 | 只看该作者
肯定会出问题,不过是早晚的事...

使用特权

评论回复
地板
yirongfu| | 2011-11-7 22:32 | 只看该作者
楼主学习很仔细:victory:

8051单片机复位后,堆栈指针SP被初始化到内部RAM地址07H,不是07F,笔误吧。

我觉得如果中断服务程序里,用户程序没有使用R0~R7这几个寄存器,而只是使用了其它自定义变量,编译器应该不会将堆栈和被使用的R0~R7重叠吧?或者说,编译器应该考虑到避开堆栈空间,这是编译器的优劣问题了。

调用函数时应该有当前PC的压栈吧,不然调用完回哪里去?

使用特权

评论回复
5
HWM| | 2011-11-7 23:29 | 只看该作者
to LZ:

参数不放在栈,但返回地址可是要入栈的。

使用特权

评论回复
6
ayb_ice| | 2011-11-8 08:00 | 只看该作者
本帖最后由 ayb_ice 于 2011-11-8 08:02 编辑

实际项目不可能用默认的堆栈初始化,肯定会重新初始化堆栈指针的,如果是C,编译器自动完成了这些动作,当然也会自动处理using关键字的...
如果用汇编,这些都是程序考虑的事了

使用特权

评论回复
7
hotpower| | 2011-11-8 09:36 | 只看该作者
51的寄存器分组就是为了减少中断保护现场。主程序不要和中断同组。若中断嵌套也不要同组。同级别中断可以同组。故寄存器只需三组就不会冲突。所以51把寄存器分为四组。合理安排即可中断少保护现场。

使用特权

评论回复
8
coody| | 2011-11-8 11:35 | 只看该作者
一般不用using,KEIL会处理,也不用管SP

使用特权

评论回复
9
原野之狼| | 2011-11-8 12:24 | 只看该作者
int main(void)
{
    foo();  /* call foo function.
                 The next instruction(after call instruction) will be pushed in stack automaticlly.
                 The address of foo was encoded in call instruction as a operand.
              */
    ...       /* return here */
}

使用特权

评论回复
10
sw008|  楼主 | 2011-11-8 20:15 | 只看该作者
这么说来,下面对于定时器中断函数,应该完全去掉里面的using语句了?也不用管SP指针?
//定时器0中断
void timer0int (void)  interrupt 1  using 2  
        {        m_time0();        }
//定时器1中断
void timer1int (void)  interrupt 3  using 3
        {        m_time1();        }

使用特权

评论回复
11
ayb_ice| | 2011-11-9 08:03 | 只看该作者
SP当然不用你管了,这些都属于内核寄存器,在C中完全由编译器管理的

使用特权

评论回复
12
渤海三叠浪| | 2011-11-9 08:09 | 只看该作者
2# ycz9999

这不我写的  我是小牛 好;P

使用特权

评论回复
13
俺土老冒| | 2015-5-20 17:14 | 只看该作者
ycz9999 发表于 2011-11-7 21:44
记得以前看到过下面这个文档  也是讲述的这个问题

谢谢您所提供的资料,过去我都是用汇编来编程的,最近越来越多的外围模块(比如说GPS模块)需要读入大量的数据进行判断处理,用汇编编写程序实在是太过庞大了,而且厂家所提供的样本程序基本上都是C编写的。所以开始尝试使用C语言编写,由于在使用汇编时,各区域的定义以及使用都需要对各指针进行预先设置(堆栈我过去一般是放在了高位128,sp从80h开始),对于低128中的00h~1fh这段地址通常作为用户指针和存放中间结果用的。问题就出现了,如果我用 data定义了变量,所保存的数据应该是在低128B的区域,而sp复位后指向了07h,这样是否会发生问题呢?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

8

主题

28

帖子

0

粉丝