1.哦,对的,第一个问题我明白了, 0x80496d8是数组的首地址,我要的函数的入口是数组首地址指向的值,谢了。
2.第二个问题,还有点不清楚。既然说是运行时产生的中断,那么为什么反汇编出来的汇编指令里面会直接有hlt:“80496d8: f4
hlt”呢?
2010/5/4 Miao@gmail <hellwolf.misty(a)gmail.com>
2010/5/3 cheng chen <freakrobot(a)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