GCC编译遇到奇葩现象:连接进奇怪的函数内容
用gcc编译了个程序,执行不正常,,用objdump提取出反汇编,,发现很奇怪的现象strcpy的反汇编如下:
一共就8条指令,,基本能看懂程序的执行流程,,这个应该是正常的
strncpy的反汇编如下:
这个一看就很奇怪,,strcpy和strncpy的功能非常类似,,不可能strcpy只需要8条指令,,而strncpy需要这么大一坨啊
而且我看了下Keil环境下的strncpy反汇编,,也是非常简单的,,
还有更奇葩的,,我在ARMv7-M Architecture Reference Manual上查了下ORR指令的编码,如下
ORR指令的最高字节显然应该是EA,,而上面反汇编出来的第一条指令却是e1803001,,最高字节是E1!!
如果说我连接的c标准库不对,,可strcpy的代码又是对的,,{:dizzy:}
哪位大侠知道这个怎么解决,,望指定 本帖最后由 wye11083 于 2019-1-15 08:39 编辑
arm高位是有条件码的,所以请相信gcc。再一个,strncpy做了很多额外工作,代码量大点很正常。还有,你说的那个8条指令的不是主函数体,仅仅是一个系统调用罢了。而后者却是个完整的函数体。也就是说,前者在libc库里有实现,后者是c语言扩展库函数,有可能只在libgcc里才有。
我说的不一定对,仅供参考。。thumb没怎么摸过,现在以mips和riscv为主,arm不开源,不用{:sweat:} wye11083 发表于 2019-1-15 07:06
arm高位是有条件码的,所以请相信gcc。再一个,strncpy做了很多额外工作,代码量大点很正常。还有,你说的 ...
厉害 wye11083 发表于 2019-1-15 07:06
arm高位是有条件码的,所以请相信gcc。再一个,strncpy做了很多额外工作,代码量大点很正常。还有,你说的 ...
感谢回答
我用的是Cortex-M单片机,,是Thumb-2指令集,,只有B有条件码,其他指令没有,而且条件码在指令编码中是能看到的
我编译的是单片机程序,,没有系统调用,,都是裸机程序,,而且strcpy那8条指令就能完成它的功能,,里面也没有系统调用相关的指令
strncpy和strcpy功能几乎完全一样,,只不过strncpy指定了最多拷贝字符个数,,应该不会复杂很多 我一眼看过去,以为是正常的,然后用Keil编译了下,发现是真的不正常,O3优化,C微库,CM3芯片反编译出来这个样,看来GCC确实混入了奇怪的东西
不使用C微库,编译出来这个样,代码真长:
takashiki 发表于 2019-1-15 09:27
我一眼看过去,以为是正常的,然后用Keil编译了下,发现是真的不正常,O3优化,C微库,CM3芯片反编译出来这 ...
多谢验证,,
长些倒没关系,,关键是现在指令是错的,,根本没法执行{:dizzy:}
我看了下ARM指令集中的ORR指令编码
cond= 0xE,表示无条件立即执行,,所以最高8位等于0xE1在ARM指令集中确实是一条ORR指令,,
也就是说gcc把ARM的库连接进我的Cortex-M单片机里面去了,,
另外,我用objdump反汇编了一下libc.a,,其中的strncpy如下:确实是ARM指令的,,
XIVN1987 发表于 2019-1-15 09:40
多谢验证,,
长些倒没关系,,关键是现在指令是错的,,根本没法执行...
从上面可以看到你的strncpy不是用thumb2编译的,全部是arm指令,这种情况的一个原因很可能链接错了库文件,前几天我也遇到过类似的情况,换了最新的编译器解决 cloudboy 发表于 2019-1-15 09:47
从上面可以看到你的strncpy不是用thumb2编译的,全部是arm指令,这种情况的一个原因很可能链接错了库文件 ...
会不会是系统里面 装个多个版本 gcc 然后一些Link指错地方了
已经确定是连接了错误的库
在arm-none-eabi\lib下有个libc.a,,是arm指令的;arm-none-eabi\lib\thumb下也有个libc.a,,是thumb指令的
连接器连接strncpy时选择了arm指令的libc.a,,
不过最奇葩的是,,连接strcpy时又是选择的thumb指令的libc.a,,
通过在连接命令中明确指定arm-none-eabi\lib\thumb\libc.a,,编译连接了正确的函数 链了错误的库
还真是
页:
[1]