首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

[求助]C51在中断里调用子程序的问题

[求助]C51在中断里调用子程序的问题

比如,当主程序main( )运行时正在调用子程序fu( ),但此时刚好发生一个中断,进入服务程序,而服务程序同样需要调用fu( ),


请问:当中断返回时,主程序main( )所调用的fu( )里面的局部变量会被破坏吗?

不会的,你出现了什么问题吗
开学了
 回来版面了
问题是自己想着想着发现出来的

我看好象应该将函数设置为重入,有个什么关键字的.
但后来我设置后,发现函数就运行不正确,在函数里面连附值都不能成功.

请问怎么完成说明函数是可重入的?

reentrant

func(/*...*/)reentrant
{
//...
}这样定义后就可以在中断和主程序中同时使用这个函数了
没错,加那个关键字说是可以的,但实际在KEIL里面函数加了这个后连参数也传递不了,很奇怪!

怎么不能传递参数?

参数是肯定能传递的.
只不过在传递的过程中,有一段代理代码将参数放到堆栈中了.
你如果在fu()函数中直接中断看参数的话,是不太明了的.

下面举例说明:
int fu(int a) reentrant
{
return a * 2;
}

void main()
{
int a;
a = fu(45);
}
; a = fu(45)
C:0x0003 7E00 MOV R6,#0x00
C:0x0005 7F2D MOV R7,#0x2D
C:0x0007 120022 LCALL fu(C:0022)
C:0x000A AD07 MOV R5,0x07
C:0x000C AC06 MOV R4,0x06
;......

; 代理代码,原本R6,R7中的参数拷贝到堆栈中了
; 这里所说的堆栈不是真正意义的堆栈,是重入函数使用参数,局部变量时使用的
; 一段内存,其处理方式类似堆栈
C:0x0022 1508 DEC ?C_IBP(0x08)
C:0x0024 1508 DEC ?C_IBP(0x08)
C:0x0026 A808 MOV R0,?C_IBP(0x08)
C:0x0028 A606 MOV @R0,0x06
C:0x002A 08 INC R0
C:0x002B A607 MOV @R0,0x07

; fu()
; 现在参数在?C_IBP指向的内存中(就是重入函数使用的参数堆栈)
C:0x002D A908 MOV R1,?C_IBP(0x08)
C:0x002F 09 INC R1
C:0x0030 E7 MOV A,@R1
C:0x0031 25E0 ADD A,ACC(0xE0)
C:0x0033 FF MOV R7,A
C:0x0034 19 DEC R1

; 如果这里被中断函数打断, 由于?C_IBP已经-2了,也就是?C_IBP指向的内存
; 已经象堆栈般调整了,下次的参数存放不会覆盖这个未执行完毕的重入函数的
; 内存空间(包括局部变量,参数的空间).
C:0x0035 E7 MOV A,@R1
C:0x0036 33 RLC A
C:0x0037 FE MOV R6,A

; OK,现在程序已经执行完毕,已经不怕覆盖它的空间了,恢复它的堆栈
C:0x0038 0508 INC ?C_IBP(0x08)
C:0x003A 0508 INC ?C_IBP(0x08)
C:0x003C 22 RET

[此贴子已经被作者于2006-3-7 15:06:32编辑过]

[此贴子已经被作者于2006-3-7 15:10:03编辑过]

返回列表