/*编译参数
NOREGPARMS 不使用寄存器传参数
RET_XSTK 使用外部数据空间作堆栈
*/
unsigned char testpara(UINT8 pa1) reentrant
{
unsigned char pa2;
pa2=pa1*5+4;
return pa2;
}
/*在程序结尾有返回代码,反汇编为:
-----------------------------------------------------------------
MOV DPTR,0x00YY ;外部堆栈指针回缩
LJMP C?ADDXBP ;外部堆栈回缩子程序
-----------------------------------------------------------------
*/
unsigned char testpara1(UINT8 pa1) reentrant
{
/*
在程序开始的地方有下面的代码:
-----------------------------------------------------------------
MOV DPTR,0x00ZZ ;外部堆栈指针增加
LJMP C?ADDXBPV ;外部堆栈增加子程序,将sp处的返回
; 地址填充到外部堆栈位置,并将XBP-2,
;注:内部堆栈sp向上加,外部堆栈XBP向下减
-----------------------------------------------------------------
*/
unsigned char pa2;
pa2=4;
return testpara(pa2);
}
/*在程序结尾有返回代码,反汇编为:
-----------------------------------------------------------------
MOV DPTR,0x00YY ;外部堆栈指针回缩
CALL C?ADDXBP ;外部堆栈回缩子程序,
;注意!!!!此处XBP(外部堆栈被缩回!!!!!!
;外部堆栈放置的返回地址丢失!!!!!!
LJMP C?RET_XBP ;从外部堆栈XBP中取出返回值,填充到SP中,
;XBP-2,SP+2,但是取出的返回地址是错误的!!!
-----------------------------------------------------------------
*/
void main(void)
{
unsigned char pa1,pa2;
pa1=5;
pa2=testpara(pa1); /*这一句可以正确返回*/
pa2=testpara1(pa1); /*这一句不可以正确返回*/
}
/* 疑点 :
1.为什么testpara函数没有testpara1头部和尾部那样的语句生成?
2.RET_XSTK究竟代表什么含义?
3.如果我希望所有传递到参数都从XBP传递,但是返回地址在SP中定义,
那该如何定义编译参数?
*/
QORSE
2003.12.25
QQ: 67897283
qorse@netease.com
感谢回帖!
FROM QORSE
感谢回帖!
需要说明的是,KEILC提供了返回地址在外部堆栈的方式,目的在于将返回地址放置到外部堆栈即XBP位置以节省硬件堆栈资源.但是按照它的生成代码方式,只有没有参数的函数才可以使用这种方式而不出错误.
现在的编译方式生成代码的顺序:
1. 调用前,加大XBP以传递函数参数(如果参数长度为Len1,则XBP - Len1)
2.CALL: 存PC返回地址到SP,SP+2,进入函数
3.将XBP大小加大2,以存放返回地址.并将返回地址移到XBP,然后SP-2
4.如果该函数有局部变量,则增加XBP以提供局部变量(如果局部变量长度为Len2则XBP - Len2).
4.进行函数过程......
5.一次缩回XBP,准备退出(如果有参数也一次缩回XBP即XBP + Len1 + Len2),问题就在这里)
6.取回返回地址,放置到sp,使SP+2, 再缩回XBP,即XBP-2(XBP是对了,但是sp中错了)
所以C51.PDF帮助文档的P75的程序不会出问题!因为Len1=Len2=0!!!
按照一般的编译原则,或许下面的过程比较合理一些:
1. 调用前,加大XBP以传递函数参数(如果参数长度为Len1,则XBP - Len1)
2.CALL: 存PC返回地址到SP,SP+2,进入函数
3.将XBP大小加大2,以存放返回地址.并将返回地址移到XBP,然后SP-2
4.进行函数过程......
5.缩回XBP(XBP + Len2)
6.取出返回地址并放到SP,SP+2,然后缩回到XBP+2
7.缩回XBP(XBP + Len1)
8.RET
但是程序结尾的 先缩回外部堆栈再取出返回地址放置到sp,应该是有问题的.