我对 ARM 处理器的内部细节不是很熟悉,但我不了解我的 Nvidia Jetson Nano 开发板上的以下行为。
C代码示例...
//main.c
#include <stdio.h>
int main()
{
int fred = 123;
int i;
for(i = -10 ; i <= 10 ; i++)
printf("%d / %d == %d\n", fred, i, fred / i);
return 0;
}
编译:
gcc main.c -ggdb
运行生成的 a.out 可执行文件会产生以下输出...
123 / -10 == -12
123 / -9 == -13
123 / -8 == -15
123 / -7 == -17
123 / -6 == -20
123 / -5 == -24
123 / -4 == -30
123 / -3 == -41
123 / -2 == -61
123 / -1 == -123
123 / 0 == 0 //unexpected!
123 / 1 == 123
123 / 2 == 61
123 / 3 == 41
123 / 4 == 30
123 / 5 == 24
123 / 6 == 20
123 / 7 == 17
123 / 8 == 15
123 / 9 == 13
123 / 10 == 12
使用 gcc 3.7 在古老的 Pentium 4 上编译的完全相同的代码会导致(如预期的那样)在i
达到 0 时抛出运行时异常并导致除以零。
Nvidia 主板运行 Ubuntu 18.04 LTS、gcc 版本 7.4.0(最新),并且在其他方面运行良好。我还编译了此代码的等效 Ada 语言版本,并按预期引发了运行时异常(因为 Ada 代表我提前进行了安全检查)。
我意识到在 C 中,“除以零会产生未定义的行为”可能是对此的解释,但是对于同一编译器套件的两个版本为同一操作提供如此不同的结果让我感到困惑。
什么情况下可能导致 Nvidia Tegra ARM(64 位)CPU 允许除以零被操作系统忽略?
编辑:/etc/cpuinfo 中有关 CPU 的详细信息...
$ cat /proc/cpuinfo
processor : 0
model name : ARMv8 Processor rev 1 (v8l)
BogoMIPS : 38.40
Features : fp asimd evtstrm aes pmull sha1 sha2 crc32
CPU implementer : 0x41
CPU architecture: 8
CPU variant : 0x1
CPU part : 0xd07
CPU revision : 1
.... truncated ....