打印

51中断保护那些寄存器需要压入堆栈

[复制链接]
8728|15
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
wangjun403|  楼主 | 2011-12-21 23:55 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 wangjun403 于 2011-12-21 23:56 编辑

51中断保护具体有那些寄存器必须要压入堆栈?那些是根据情况来定的

如果有根据情况来定的,这个情况是什么?

硬件中断和函数调用需要保存的寄存器是不是一样的?

希望大侠可以讲的详细点

相关帖子

沙发
dengm| | 2011-12-22 00:11 | 只看该作者
硬件中断中, 独占的资源以外的 所有使用的资源, 都要保护。

使用特权

评论回复
板凳
ayb_ice| | 2011-12-22 08:28 | 只看该作者
中断里使用到的公共资源都要保护

使用特权

评论回复
地板
wangjun403|  楼主 | 2011-12-22 08:54 | 只看该作者
怎么才会知道正在使用的有哪些资源呢

使用特权

评论回复
5
wangjun403|  楼主 | 2011-12-22 09:17 | 只看该作者
看了下调用子函数的时候对应的汇编也没有push语句什么的

这个寄存器保护是怎么实现的?

使用特权

评论回复
6
DianGongN| | 2011-12-22 11:57 | 只看该作者
通常情况下,psw acc B dptr都需要保护
如果中断服务程序和主程序用同一组工作寄存器,则R0 R1 ... R7也需要保护

使用特权

评论回复
7
wangjun403|  楼主 | 2011-12-22 19:13 | 只看该作者
为什么调用子函数的时候对应的汇编也没有push语句什么的呢?

使用特权

评论回复
8
DianGongN| | 2011-12-22 20:19 | 只看该作者
本帖最后由 DianGongN 于 2011-12-22 20:22 编辑

调用子函数和执行中断服务程序是不同的。

调用子函数可以在调用之前安排保护现场。很多情况下不需要保护。这样,在子函数中可以不写保护现场程序段。只要说明哪些资源的值被改变即可。

执行中断服务程序完全不一样,没有调用一说。主程序可能在任何时刻被中断,主程序中无法安排保护现场,必须在中断服务程序中安排保护现场和恢复现场

使用特权

评论回复
9
wukunshan| | 2011-12-23 09:31 | 只看该作者
虚心受教。。。

使用特权

评论回复
10
wangjun403|  楼主 | 2011-12-23 10:10 | 只看该作者
8# DianGongN

你说的很有道理

“调用子函数可以在调用之前安排保护现场。很多情况下不需要保护”
如果需要,这个保护怎么安排?

为什么很多情况下都不需要呢?

使用特权

评论回复
11
DianGongN| | 2011-12-23 23:00 | 只看该作者
本帖最后由 DianGongN 于 2011-12-23 23:02 编辑

看了lz在4L的发言,才知道楼主没有完全理解保护现场的含义。

这个现场指的是子程序或中断服务程序中,哪些被修改了数值的共用资源,通常就是PSW Acc  B DPTR,R0 R1 R2.....R7,这些资源是各种程序都要用的。

你如果在中断服务程序中改变了psw acc 和R0的值,那就一定要保护psw acc 和R0,返回之前恢复。B PSW R1 R2.....R7的值你没有改变,当然就不需要保护。这个是一目了然的。

那为什么子程序很多时候不需要保护呢?
假设你写了个子程序,求n个单元中单字节数据的累加和。在子程序中,你改变了进位C即psw,还改变了acc和R0,但你不一定要保护它们,只要在子程序的说明部分写明你改变了psw acc R0就行了。
主程序调用的时候自然知道psw acc R0要不要保护。一般情况下,psw acc R0在调用子程序后,并不需要保持原来的值不变,所以主程序和子程序都不需要保护。

使用特权

评论回复
12
刘前辈| | 2011-12-25 15:05 | 只看该作者
本帖最后由 刘前辈 于 2011-12-25 15:18 编辑
假设你写了个子程序,求n个单元中单字节数据的累加和。在子程序中,你改变了进位C即psw,还改变了acc和R0,但你不一定要保护它们,只要在子程序的说明部分写明你改变了psw acc R0就行了。主程序调用的时候自然知道psw acc R0要不要保护。一般情况下,psw acc R0在调用子程序后,并不需要保持原来的值不变,所以主程序和子程序都不需要保护。


我还是没弄明白:按照11楼的说法,难道我写任何C函数(子程序,过程) 还要了解我的程序里到底用了哪些寄存器资源(像R0,ACC,进位C)吗?——那是C编译器的事,我怎么可能知道?换个编译器使用的寄存器资源又不一样了;像 *( p+ i )=aaa[(cor+ i ) %5];  这样的C语句,我怎么可能写明我具体改变了哪些资源( B还是DPTR)?

LZ问的有道理,“很多情况下不需要保护。” ???
很多是指那些情况? 很少又是指哪些情况需要保护(除中断函数之外)?

——有确定规则吗?我怎么知道正常调用函数时哪些情况是属于“很多”(无需保护),哪些情况属于“很少”(需要保护,除了中断异步情况)?


俺智商不高,也和LZ一样问题请教高手。
  
   
、、

使用特权

评论回复
13
DianGongN| | 2011-12-25 19:59 | 只看该作者
不好意思,我是站在汇编的角度说这些问题的。
楼主和前辈要是指c语言,本人不会,没用过,上面说的都无效。

正打算学习keil c,到时候再请教楼主和前辈。

使用特权

评论回复
14
DownCloud| | 2011-12-26 07:53 | 只看该作者
c子程序当然不必保护,每个子程序开头就来个局部变量初始化(有可能是寄存器)
所以和前一次用的寄存器无关。
这是编程习惯问题,汇编写过,但我从来不在主程序,子程序保护寄存器。我的做法和c编译器一样。

使用特权

评论回复
15
刘前辈| | 2011-12-26 18:28 | 只看该作者
本帖最后由 刘前辈 于 2011-12-26 18:51 编辑

51中断函数需要保存哪些寄存器是由C编译器决定的,用户不关心。

硬件中断和函数调用需要保存的寄存器是两回事。

子函数调用,私有存储区使用的是“堆”——即编译器分配在全局变量后面的“共享覆盖区域”,因为同步调用,所以可以多函数共享/ 覆盖。——所以可重入函数私有堆栈不能使用共享覆盖区域;只能使用私有“栈”。这就是reentrant 关键字告诉编译器的策略内容。

而中断函数是异步调用,其数据存贮区不可能使用共享覆盖区,因此 ISR 使用的是“栈”—— 被中断函数打断的主函数的私有栈(或寄存器)。所以需要保护/ 恢复。




、、

使用特权

评论回复
16
wangjun403|  楼主 | 2011-12-29 21:28 | 只看该作者
谢谢两位

使用特权

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

本版积分规则

个人签名:数学才不是浮云

0

主题

629

帖子

1

粉丝