XIVN1987 发表于 2019-1-14 23:10:58

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 07:06:32

本帖最后由 wye11083 于 2019-1-15 08:39 编辑

arm高位是有条件码的,所以请相信gcc。再一个,strncpy做了很多额外工作,代码量大点很正常。还有,你说的那个8条指令的不是主函数体,仅仅是一个系统调用罢了。而后者却是个完整的函数体。也就是说,前者在libc库里有实现,后者是c语言扩展库函数,有可能只在libgcc里才有。


我说的不一定对,仅供参考。。thumb没怎么摸过,现在以mips和riscv为主,arm不开源,不用{:sweat:}

love_zjb 发表于 2019-1-15 07:57:58

wye11083 发表于 2019-1-15 07:06
arm高位是有条件码的,所以请相信gcc。再一个,strncpy做了很多额外工作,代码量大点很正常。还有,你说的 ...

厉害

XIVN1987 发表于 2019-1-15 08:53:34

wye11083 发表于 2019-1-15 07:06
arm高位是有条件码的,所以请相信gcc。再一个,strncpy做了很多额外工作,代码量大点很正常。还有,你说的 ...


感谢回答

我用的是Cortex-M单片机,,是Thumb-2指令集,,只有B有条件码,其他指令没有,而且条件码在指令编码中是能看到的


我编译的是单片机程序,,没有系统调用,,都是裸机程序,,而且strcpy那8条指令就能完成它的功能,,里面也没有系统调用相关的指令

strncpy和strcpy功能几乎完全一样,,只不过strncpy指定了最多拷贝字符个数,,应该不会复杂很多

takashiki 发表于 2019-1-15 09:27:17

我一眼看过去,以为是正常的,然后用Keil编译了下,发现是真的不正常,O3优化,C微库,CM3芯片反编译出来这个样,看来GCC确实混入了奇怪的东西

不使用C微库,编译出来这个样,代码真长:

XIVN1987 发表于 2019-1-15 09:40:50

takashiki 发表于 2019-1-15 09:27
我一眼看过去,以为是正常的,然后用Keil编译了下,发现是真的不正常,O3优化,C微库,CM3芯片反编译出来这 ...


多谢验证,,

长些倒没关系,,关键是现在指令是错的,,根本没法执行{:dizzy:}

XIVN1987 发表于 2019-1-15 09:46:35


我看了下ARM指令集中的ORR指令编码

cond= 0xE,表示无条件立即执行,,所以最高8位等于0xE1在ARM指令集中确实是一条ORR指令,,

也就是说gcc把ARM的库连接进我的Cortex-M单片机里面去了,,

另外,我用objdump反汇编了一下libc.a,,其中的strncpy如下:确实是ARM指令的,,

cloudboy 发表于 2019-1-15 09:47:05

XIVN1987 发表于 2019-1-15 09:40
多谢验证,,

长些倒没关系,,关键是现在指令是错的,,根本没法执行...

从上面可以看到你的strncpy不是用thumb2编译的,全部是arm指令,这种情况的一个原因很可能链接错了库文件,前几天我也遇到过类似的情况,换了最新的编译器解决

浮华一生 发表于 2019-1-15 10:00:27

cloudboy 发表于 2019-1-15 09:47
从上面可以看到你的strncpy不是用thumb2编译的,全部是arm指令,这种情况的一个原因很可能链接错了库文件 ...

会不会是系统里面 装个多个版本 gcc 然后一些Link指错地方了

XIVN1987 发表于 2019-1-15 11:21:19


已经确定是连接了错误的库

在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,,编译连接了正确的函数

SCREA 发表于 2021-10-16 15:09:08

链了错误的库
还真是
页: [1]
查看完整版本: GCC编译遇到奇葩现象:连接进奇怪的函数内容