函数指针中的最低有效位

问题描述 投票:0回答:4

我正在研究一种编程语言实现,我想知道如何(错误地)建议将函数指针的最低有效位压入服务来存储数据。

是否有任何主要平台(AMD64/{Windows/Linux/MacOS}、Arm/{iOS、Android})中函数指针的 2 个最低有效位不为零? 也就是说,代码在主要平台上的对齐方式是否至少为 4?

c pointers assembly compiler-construction cpu
4个回答
6
投票

我可以告诉你,Apple 的 64 位运行时(我认为是 ARM64 和 Intel)按照你的建议广泛使用最低有效位作为标志。在 Objective-C 中,一切都是对象,并且为了与 C 兼容,几乎每个对象都存在于堆中并由其指针记录。在 64 位模式下,他们允许非常小的对象存在于堆栈中,方法是将它们放入 62 位并使用低两位来指示这实际上不是一个指针,而是一个文字对象。因此,您可以将短字符串、对象包装的 32 位及以下数字等直接放入“指针”中,而不将任何内容放在堆上。

然而,Apple 不会在 32 位运行时中执行此操作(即使是 iOS 上的“现代”运行时)。因此,可能值得研究一下为什么会这样。诚然,这可能只是因为 PowerPC 遗留下来的一些架构怪癖。

正如评论中向我指出的那样(以及为什么现在将其标记为社区 wiki),C 标准区分了 function 指针的存储和所有其他类型的指针。因此,上面的评论可能相关,也可能不相关——尽管如此,我相信这是因为闭包再次与数据和函数分开,在编译语言中,代码本身通常已经提前编译,而闭包本身只是要执行的数据。填补空白。但我想说的是,有一些可靠的系统,假设它们可以在需要对齐的系统上重用指针的最低有效位。


4
投票

ARM 有两种模式† - 传统模式(又名“ARM”)和 Thumb。在 ARM 模式下,指令在 4 字节边界上对齐,在 Thumb 中则在 2 字节边界上对齐。 CPU 使用第 0 位来调用切换模式:要从 ARM 转到 Thumb,您可以向地址发出分支和切换模式命令,并将其最右边的位设置为 1。

在两个最流行的基于 ARM 的平台(iOS 和 Android)上,本机用户态代码的首选模式恰好是 Thumb。但必须支持与 ARM 的互操作。因此地址中实际上没有未使用的位。

†实际上更多。


1
投票

在ARM上,低位有特殊含义:它在Thumb和传统模式之间切换。在 Thumb 模式下,指令是 16 位对齐的,因此这两个位都会被使用。

在 AMD64 和 x86 上,根据优化模式,函数可能位于奇数地址。这意味着低两位始终在使用中。


-2
投票

没有一个主要的现代平台不要求其指令至少 4 字节对齐,而且我不知道有哪个 C 编译器会使用低字节来达到自己的目的。等等关于 C 中强制转换指针操作的未定义行为,但你是安全的。

编辑:如下所述,对于 ARM Thumb,您只能获得一位,并且您需要确保在跳转之前清除它。对于 i386,某些链接器在禁用优化时不会进行对齐。

© www.soinside.com 2019 - 2024. All rights reserved.