请教大家2个问题,谢谢: 1.函数指针,断错误无法解决 #include<stdio.h> #define FUNC(x) ((void(*)()) *(x))
void aa(){ printf("aa\n");} void bb(){ printf("bb\n");} void cc(){ printf("cc\n"); } void dd(){ printf("dd\n");}
void* operate[] = {aa,bb,cc,dd};
int main() { printf("%x\n",operate); (*(void(*) () ) 0x80496d8)(); //这个“断错误”了 //我这里的0x80496d8就是前面打印出来的operate的地址,应该就是指向aa函数的指针的地址么 //我用的格式跟《C陷阱与缺陷》P15 的方式一样的(*(void (*) 0))(); 将入口地址强制转化为函数么 ((void(*) () ) *operate)(); //这个正确的 //FUNC(operate+1)(); //这个跟上面那个一致的,也“断错误”了 return 0; }
于是我把它编程汇编指令,太长了粘个主函数 main: pushl %ebp movl %esp, %ebp andl $-16, %esp subl $16, %esp movl $.LC4, %eax movl $operate, 4(%esp) movl %eax, (%esp) call printf movl $134518488, %eax ;这个$134518488我看过了就是0x80496d8,那不是跟下面的operate应该是一样的么 call *%eax movl operate, %eax ;这个operate应该也是$134518488,不是吗? call *%eax movl $0, %eax leave ret .size main, .-main
2.另外一个问题,断错误的停机指令是何时生成的? 还是上面程序,我用objdump反汇编找0x80496d8这个地址 80496d8: f4 hlt 80496d9: 83 04 08 08 addl $0x8,(%eax,%ecx,1) 怎么这里就有hlt指令了,是gcc编译的时候就生成hlt指令了吗?而不是运行出了错误才要停机的?
纠结,非常感谢~
P.S. 附件内容(都是纯文本的): 源程序: pointerfunc.c 生成的汇编:pointerfunc.s 反汇编结果:func.s
2010/5/3 cheng chen freakrobot@acm.org:
请教大家2个问题,谢谢: 1.函数指针,断错误无法解决 #include<stdio.h> #define FUNC(x) ((void(*)()) *(x))
void aa(){ printf("aa\n");} void bb(){ printf("bb\n");} void cc(){ printf("cc\n"); } void dd(){ printf("dd\n");}
void* operate[] = {aa,bb,cc,dd};
int main() { printf("%x\n",operate); (*(void(*) () ) 0x80496d8)();
(*(void(**) () ) 0x80496d8)();
改成这样就好了,原因就是少了个 '*'
//这个"断错误"了 //我这里的0x80496d8就是前面打印出来的operate的地址,应该就是指向aa函数的指针的地址么 //我用的格式跟《C陷阱与缺陷》P15 的方式一样的(*(void (*) 0))(); 将入口地址强制转化为函数么 ((void(*) () ) *operate)(); //这个正确的 //FUNC(operate+1)(); //这个跟上面那个一致的,也"断错误"了 return 0; }
于是我把它编程汇编指令,太长了粘个主函数 main: pushl %ebp movl %esp, %ebp andl $-16, %esp subl $16, %esp movl $.LC4, %eax movl $operate, 4(%esp) movl %eax, (%esp) call printf movl $134518488, %eax ;这个$134518488我看过了就是0x80496d8,那不是跟下面的operate应该是一样的么 call *%eax movl operate, %eax ;这个operate应该也是$134518488,不是吗? call *%eax movl $0, %eax leave ret .size main, .-main
2.另外一个问题,断错误的停机指令是何时生成的? 还是上面程序,我用objdump反汇编找0x80496d8这个地址 80496d8: f4 hlt 80496d9: 83 04 08 08 addl $0x8,(%eax,%ecx,1) 怎么这里就有hlt指令了,是gcc编译的时候就生成hlt指令了吗?而不是运行出了错误才要停机的?
段错误是机器产生了错误中断后发生 SIGSEG 信号,然后程序收到后默认信号处理程序就是停止进程。
1.哦,对的,第一个问题我明白了, 0x80496d8是数组的首地址,我要的函数的入口是数组首地址指向的值,谢了。
2.第二个问题,还有点不清楚。既然说是运行时产生的中断,那么为什么反汇编出来的汇编指令里面会直接有hlt:“80496d8: f4 hlt”呢?
2010/5/4 Miao@gmail hellwolf.misty@gmail.com
2010/5/3 cheng chen freakrobot@acm.org:
请教大家2个问题,谢谢: 1.函数指针,断错误无法解决 #include<stdio.h> #define FUNC(x) ((void(*)()) *(x))
void aa(){ printf("aa\n");} void bb(){ printf("bb\n");} void cc(){ printf("cc\n"); } void dd(){ printf("dd\n");}
void* operate[] = {aa,bb,cc,dd};
int main() { printf("%x\n",operate); (*(void(*) () ) 0x80496d8)();
(*(void(**) () ) 0x80496d8)();
改成这样就好了,原因就是少了个 '*'
//这个"断错误"了 //我这里的0x80496d8就是前面打印出来的operate的地址,应该就是指向aa函数的指针的地址么 //我用的格式跟《C陷阱与缺陷》P15 的方式一样的(*(void (*) 0))(); 将入口地址强制转化为函数么 ((void(*) () ) *operate)(); //这个正确的 //FUNC(operate+1)(); //这个跟上面那个一致的,也"断错误"了 return 0; }
于是我把它编程汇编指令,太长了粘个主函数 main: pushl %ebp movl %esp, %ebp andl $-16, %esp subl $16, %esp movl $.LC4, %eax movl $operate, 4(%esp) movl %eax, (%esp) call printf movl $134518488, %eax ;这个$134518488我看过了就是0x80496d8,那不是跟下面的operate应该是一样的么 call *%eax movl operate, %eax ;这个operate应该也是$134518488,不是吗? call *%eax movl $0, %eax leave ret .size main, .-main
2.另外一个问题,断错误的停机指令是何时生成的? 还是上面程序,我用objdump反汇编找0x80496d8这个地址 80496d8: f4 hlt 80496d9: 83 04 08 08 addl $0x8,(%eax,%ecx,1) 怎么这里就有hlt指令了,是gcc编译的时候就生成hlt指令了吗?而不是运行出了错误才要停机的?
段错误是机器产生了错误中断后发生 SIGSEG 信号,然后程序收到后默认信号处理程序就是停止进程。 _______________________________________________ Chinese mailing list Chinese at lists.fedoraproject.org https://admin.fedoraproject.org/mailman/listinfo/chinese
2010/5/3 cheng chen freakrobot@acm.org:
2.第二个问题,还有点不清楚。既然说是运行时产生的中断,那么为什么反汇编出来的汇编指令里面会直接有hlt:"80496d8: f4 hlt"呢?
哦,我搞错你的意思了。
其实这个地址包含的是一个指针数据,而不是代码,所以反汇编的结果没有意义。
我前面解释的那什么 hlt 应该不正确,忽略吧。
哦,彻底明白了,谢谢了:)
2010/5/4 Miao@gmail hellwolf.misty@gmail.com
2010/5/3 cheng chen freakrobot@acm.org:
2.第二个问题,还有点不清楚。既然说是运行时产生的中断,那么为什么反汇编出来的汇编指令里面会直接有hlt:"80496d8: f4 hlt"呢?
哦,我搞错你的意思了。
其实这个地址包含的是一个指针数据,而不是代码,所以反汇编的结果没有意义。
我前面解释的那什么 hlt 应该不正确,忽略吧。 _______________________________________________ Chinese mailing list Chinese at lists.fedoraproject.org https://admin.fedoraproject.org/mailman/listinfo/chinese
chinese@lists.fedoraproject.org