查看程序集输出,我们可以看到两个文件中存在差异。
In test_nativ
:
86ec: 4602 mov r2, r0
86ee: 460b mov r3, r1
86f0: f241 0044 movw r0, #4164 ; 0x1044
86f4: f2c0 0001 movt r0, #1
86f8: f7ff ef5c blx 85b4 <_init+0x20>
这是通过一个double
in r2:r3
, and std::cout
in r0
.
In test_cc
:
86d8: e28f3068 add r3, pc, #104 ; 0x68
86dc: e1c320d0 ldrd r2, [r3]
86e0: e14b21f4 strd r2, [fp, #-20] ; 0xffffffec
86e4: e3010040 movw r0, #4160 ; 0x1040
86e8: e3400001 movt r0, #1
86ec: ed1b0b03 vldr d0, [fp, #-12]
86f0: ebffffa5 bl 858c <_init+0x20>
这通过了一个double
in d0
(VFP 寄存器),以及std::cout
in r0
。在这里观察一下r2:r3
已加载(通过ldrd
)与第二次打印的浮点值,即 0.0。因为动态链接的ostream::operator<<(double val)
期望它的论点r2:r3
, 首先打印出0。
我也可以解释第二个看起来很奇怪的浮动。这是第二个浮点数的打印位置:
8708: e1a03000 mov r3, r0
870c: e1a00003 mov r0, r3
8710: ed1b0b05 vldr d0, [fp, #-20] ; 0xffffffec
8714: ebffff9c bl 858c <_init+0x20>
看到那个r3
被设定为r0
,地址cout
。从上面,r0 = 0x011040
。因此,寄存器对r2:r3
变为 0x0001104000000000,解码为双精度数 1.478946186471156e-309。
所以问题是你的桌面 GCC 库使用了 VFP/NEON 指令,而设备上的动态库不使用这些指令。如果你使用-static
,您获得了 VFP/NEON 库,一切又恢复正常了。
我的建议只是找出设备和编译器库不同的原因,并解决这个问题。