打印
[C语言]

【求助】关于函数指针的获取

[复制链接]
2329|15
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
lzp3520265|  楼主 | 2013-9-26 21:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 lzp3520265 于 2013-9-26 21:05 编辑

以51为例
void cc()
{
}
void main()
{
    char ccH,ccL;
}
cc是一个函数指针。
应该是由三个字节组成的:第一个字节是指针的类型。
                        第二个字节是指向函数地址的高8位
                        第三个字节是指向函数地址的低8位
那么如何将函数地址的高8位和低8位赋值给ccH和ccL呢?类似这样。
char *ccP=&cc;
ccH=*(ccP+1);
ccL=*(ccP+2);
但是我希望能直接通过类似这样的方式获取,当然编译通不过。
ccH=cc>>8
ccL=cc>>16
就是说通过编译器直接获取cc的高低地址,而不是通过代码运算。

相关帖子

沙发
ayb_ice| | 2013-9-27 07:51 | 只看该作者
定义一个函数指针变量,然后赋值

void (*pf)(void);

pf  = cc;

使用特权

评论回复
板凳
q3742829| | 2013-9-27 11:22 | 只看该作者
过来学习

使用特权

评论回复
地板
w522930954| | 2013-9-27 15:03 | 只看该作者
函数指针不能赋值给char型指针。。

使用特权

评论回复
5
xlsbz| | 2013-9-27 22:29 | 只看该作者
函数指针 和变量指针本质上 都差不多

使用特权

评论回复
6
xiaoyuan_ly| | 2013-10-9 21:49 | 只看该作者
"就是说通过编译器直接获取cc的高低地址,而不是通过代码运算 ” 这好像不行吧?! 这样你看行不行,用汇编来解决,找出C编译器cc函数的符号表示直接情况,用汇编来避开C语言规则的安全壁垒,那时的C规则就是浮云了,什么数据类型,你自己随便玩;但好像还是要通过汇编代码的赋值运算了。你看是不是有这个可能? 我只是想了下,没实践过。

使用特权

评论回复
7
xiaoyuan_ly| | 2013-10-9 22:06 | 只看该作者
想了下,你看这样行不?! 先在C中定义 void cc(void) {} 和 void (* const p)(void) {} , 然后 p = cc; 接着在编译后找出这个p符号在汇编后的符号表示,这时应该是一个函数常量符号(其值就是cc地址),如 _p什么之类的表示,再在你需要的地方嵌入汇编代码。 这样我想应该可以避开C编译器的规则壁垒了吧?!

使用特权

评论回复
8
xiaoyuan_ly| | 2013-10-9 22:10 | 只看该作者
哦对了,把这2个函数定义成全局外链接的,应该会好找点(找到那个汇编下的符号)。

使用特权

评论回复
9
xiaoyuan_ly| | 2013-10-9 22:36 | 只看该作者
我刚才翻了下51汇编书,关键是要找到C编译之后,这个函数cc函数名符号在汇编中的表述:如_?cc  那么就可以用这个_?cc直接进行汇编操作。
如下:
_asm
  MOV DPTR,#_?cc
  MOV _?ccH,DPH
  MOV _?ccL,DPL
_endasm

使用特权

评论回复
10
xiongxiaoshuang| | 2013-10-9 23:26 | 只看该作者
:)

使用特权

评论回复
11
chenbb8| | 2013-10-9 23:35 | 只看该作者
xiaoyuan_ly 发表于 2013-10-9 22:06
想了下,你看这样行不?! 先在C中定义 void cc(void) {} 和 void (* const p)(void) {} , 然后 p = cc;  ...

不用那么复杂的,直接用union就行了,将值赋给union中的函数指针变量,再当作字节用就OK了。
需要注意的是C51是大端的~

问下C51的函数指针地址是3字节的啊?
STM8倒是可以通过设置更换默认程度的函数指针,或者通过扩展的指令来设置对应函数指针的位数。
64K的STM8必须要选择3字节的才能通过编译。

使用特权

评论回复
12
annwa| | 2013-10-10 10:01 | 只看该作者
重来没用过函数指针!!

使用特权

评论回复
13
lzp3520265|  楼主 | 2013-10-10 19:25 | 只看该作者
本帖最后由 lzp3520265 于 2013-10-10 19:31 编辑
chenbb8 发表于 2013-10-9 23:35
不用那么复杂的,直接用union就行了,将值赋给union中的函数指针变量,再当作字节用就OK了。
需要注意的 ...

从keil仿真的结果来看,是三个字节。一个字节表示类型,两个字节表示地址。
现在我发现只要将函数地址转类型赋值给int(16位),就可以得到地址。比如
unsigned char add[2];
void fun(){}
*(int*)add=fun;
这样add[0]是高八位add[1]是低八位。
把指针定义成union还重来没试过,不过感觉貌似很可行啊……

使用特权

评论回复
14
lzp3520265|  楼主 | 2013-10-10 19:36 | 只看该作者
本帖最后由 lzp3520265 于 2013-10-10 19:37 编辑
xiaoyuan_ly 发表于 2013-10-9 22:36
我刚才翻了下51汇编书,关键是要找到C编译之后,这个函数cc函数名符号在汇编中的表述:如_?cc  那么就可以 ...

恩,类似的方法我试过,是可行的。但虽然我是混编,但是有写地方这样写太不方便。不过C的我也已经解决了。
汇编的可以这样
MOV DPTR,#_?cc
;或者是
MOV DPH,#HIGH _?cc
MOV DPL,#LOW _?cc

使用特权

评论回复
15
wuzx-61| | 2013-10-10 19:58 | 只看该作者

使用特权

评论回复
16
chenbb8| | 2013-10-10 20:57 | 只看该作者
lzp3520265 发表于 2013-10-10 19:25
从keil仿真的结果来看,是三个字节。一个字节表示类型,两个字节表示地址。
现在我发现只要将函数地址转类 ...

试下union咯,你这种强制转换的做法不规范,因为带有隐性转换,可能会有警告。

使用特权

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

本版积分规则

8

主题

41

帖子

0

粉丝