在x86_32/64中,在指针和整数之间进行强制转换

Cast between a pointer and integer in x86_32/64

本文关键字:之间 整数 转换 指针 x86      更新时间:2023-10-16

我有一个简单的虚拟机,我做它是为了好玩。它在一个非常低的层次上工作,并且没有任何类型的概念。一切都只是一个整数。有一些获取指针和通过指针访问内存的指令。问题是,这些指针被简单地存储为uint64_t,并且任何指针算术都是整数算术。当将其用作指针时,机器将其强制转换为void*。这类代码在汇编级是显而易见的,但C和C++标准不允许程序员安全地进行整数指针转换,尤其是当整数用于更改指针值时。

我不会让这个玩具虚拟机到处都是便携式的。它只是被期望在x86_32/64机器下工作,即使在完全的编译器优化之后,它似乎也能很好地工作。我认为这是因为指针在x86体系结构中被表示为整数没有什么不同。

在这种情况下,通常会应用什么样的解决方案,即语言标准没有声明某些代码是安全的,但它在目标硬件中确实应该是安全的——结果看起来确实不错?

或者作为一个更实际的问题,我如何才能让编译器(gcc)不对这样的代码执行破坏性优化

uint64_t registers[0x100];
registers[0] = (uint64_t)malloc(8);
registers[0] += 4;
registers[2] = 0;
memcpy(&registers[2], (void*)registers[0], 4);

上面不是真正的代码,但字节码指令的某个序列实际上会做与上面类似的事情。

如果您真的需要向整数投射指针,请至少使用uintptr_t,看在意大利面条怪物的份上!此类型(及其签名的对应类型)意味着可以安全地向指针进行强制转换。然而,它不用于操作(但对于线性模型来说可能是安全的,不修改这两个值的表示)。

尽管如此,您的代码似乎没有意义,但可能会阻碍编译器主动进行优化。我想说,如果不更深入地了解你打算完成什么,很可能会有更好的方法。