求助:ICCAVR函数入口地址问题
一直用ICCAVR,最近做一个小项目,需要在程序中获取某函数的入口地址,发现用“&”取函数地址,用“*”函数指针等等各种传统方法,获取的都不是真实的函数入口地址,但获取变量的地址就没问题,网上查了一整天,发现也有很多人发现了这个问题,据说是ICCAVR在处理函数地址以及函数指针时,返回的不是函数入口在SRAM中的实际地址,而是一个在SRAM中的“数据表”的地址,该“数据表”中存放的数据是各函数的入口地址,也就是说,用C的传统方法获取函数入口地址在ICCAVR中行不通(CVAVR,GCCAVR似乎没这问题?)。请教高手来指点一下这个问题怎么解决?
例:
unsigned int TIME_Light=0xafaf; //背光计时器
unsigned int AQ_ADC[]=
{0xfcfc,0,0,0,0,0,0,0};//缓冲区
unsigned int Addr_A;
unsigned int Addr_B;
unsigned int Addr_C;
unsigned int Addr_D;
void port_init(void)
{
.....
}
void main (void)
{
......
}
void get_Addr (void)
{
Addr_A=(unsigned int)&TIME_Light;// 正确
Addr_B=(unsigned int)&AQ_ADC; // 这两个获得正确的变量存放地址的两字节数据
Addr_C=(unsigned int)&port_init; // 错误
Addr_D=(unsigned int)&main; // 这两个获得的数据并非真实的函数入口地址数据
} 在线等,实在不想换编译器啊 可以参考 菜单的做法
菜单里的函数调用 肯请LS详细说明,在ICCAVR中的实现方法。在标准C中那是地球人都知道。 ICC 这个是有点问题,我也没完全搞懂,但是我有个方法解决。
比如你的函数名是Task();你可以这样处理:
temp_l = (unsigned char)((unsigned int)Task & 0xff);
temp_h = (unsigned char)((unsigned int)Task >> 8);
asm("LDS R30,%temp_l");
asm("LDS R31,%temp_h");
asm("LPM");
asm("STS %temp_l,R0");
asm("ADIW R30,0x01");
asm("LPM");
asm("STS %temp_h,R0");
之后temp_h和tamp_l里就是函数地址的高低字节了。
嵌入了汇编,但是要注意使用前把用到的寄存器入栈,用完后出栈。temp_h和tamp_l是unsigned char型的变量。 按楼上的办法写了一个函数:
unsigned int GET_funcAddr(unsigned char *funcName)
{
union AA
{
unsigned int temp_int;
unsigned char temp;
}Addr;
Addr.temp_int = (unsigned int)funcName;
temp_l=Addr.temp;
temp_h=Addr.temp;
//temp_l = (unsigned char)((unsigned int)funcName & 0xff);
//temp_h = (unsigned char)((unsigned int)funcName >> 8);
asm("PUSH R30");
asm("PUSH R31");
asm("PUSH R0");
asm("LDS R30,%temp_l");
asm("LDS R31,%temp_h");
asm("LPM");
asm("STS %temp_l,R0");
asm("ADIW R30,0x01");
asm("LPM");
asm("STS %temp_h,R0");
asm("POP R0");
asm("POP R31");
asm("POP R30");
Addr.temp = temp_l;
Addr.temp = temp_h;
return Addr.temp_int;
}
问题依旧,哎~~~ 是不是得换编译器了,我用的ICCAVR6.13 回复【5楼】liang-s
-----------------------------------------------------------------------
这个我也不知道了
我用的icc7.1几 的,是可以的 我也遇到这问题,郁闷啊 why do you want to know the address of a function? what does knowing it do that you cannot achieve via other means, like a pointer to a function? Addr_C=(unsigned int)&port_init; // 错误
~~~~~~~~~~~~~~~~
我的理解是这样的:
1.你的函数代码段是放在FLASH区域的;
2.而你的语法是引用RAM区域的内容
so 这个是不可能正常的。
其实在C语言中早就有函数指针的写法,你这样写是不符合规范的
你在百度中就可以授到得内容
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int func(int x); /* 声明一个函数 */
int (*f) (int x); /* 声明一个函数指针 */
f=func; /* 将func函数的首地址赋给指针f */
赋值时函数func不带括号,也不带参数,由于func代表函数的首地址,因此经过赋值以后,指针f就指向函数func(x)的代码的首地址。 注2:函数括号中的形参可有可无,视情况而定。
下面的程序说明了函数指针调用函数的方法:
例一、
#include<stdio.h>
int max(int x,int y)
{ return(x>y?x:y); }
void main()
{
int (*ptr)(int, int);
int a,b,c;
ptr=max;
scanf("%d,%d",&a,&b);
c=(*ptr)(a,b);
printf("a=%d,b=%d,max=%d",a,b,c);
} 有方法了
unsigned int addr;
addr=*(unsigned int const *)_task1;
页:
[1]