gpt4 book ai didi

64-bit - 为什么 x64 操作系统可以运行为 x86 机器编译的代码

转载 作者:行者123 更新时间:2023-12-02 22:33:34 30 4
gpt4 key购买 nike

基本上,我想知道 x86-64 操作系统为什么可以运行为 x86 机器编译的代码。我知道当第一个 x64 系统被引入时,这不是它们中任何一个的特性。之后,他们以某种方式设法做到了这一点。

请注意,我知道 x86 汇编语言是 x86-64 汇编语言的一个子集,ISA 的设计方式使其可以支持向后兼容。但是让我困惑的是堆栈调用约定。这些约定因架构而异。例如,在 x86 中,为了备份帧指针,进程将其指向堆栈(RAM)的位置压入并在完成后弹出。另一方面,在 x86-64 中,进程根本不需要更新帧指针,因为所有引用都是通过堆栈指针给出的。其次,虽然在 x86 架构中函数的参数是通过 x86-64 中的堆栈传递的,但寄存器用于此目的。

也许 x86-64 和 x64 架构的堆栈调用约定之间的这种差异可能不会影响程序堆栈增长的方式,只要不同的约定不会同时使用,并且这种情况主要是因为 x32 函数被其他调用x32 和 x64 相同。但是,在某一时刻,一个函数(可能是一个系统函数)将调用一个函数,该函数的代码是为带有一些参数的 x86-64 机器编译的,在这一点上,我很好奇操作系统(或其他一些控制单元)如何处理让这个功能工作。

提前致谢。

最佳答案

i386/x86-64 架构的部分设计方式是 CS和其他段寄存器引用 GDT 中的条目. GDT 条目除了描述当前运行任务的操作模式和特权级别的基本和限制之外还有一些特殊位。

如果CS寄存器引用一个32位code segment , 处理器将在本质上是 i386 兼容模式下运行。同样,64 位代码需要一个 64 位代码段。

所以,把这些放在一起。

当操作系统想要运行一个 32 位任务时,在任务切换期间,它会加载一个值到 CS 中,该值指向一个 32 位代码段。中断处理程序也有与其关联的段寄存器,因此当系统调用发生或中断发生时,处理程序将切换回操作系统的 64 位代码段,(允许 64 位操作系统代码正确运行)和操作系统然后可以完成它的工作并继续安排新任务。

作为关于调用约定的跟进。 i386 或 x86-64 都不需要使用帧指针。代码可以随心所欲地自由发挥。事实上,许多编译器(gcc、clang、VS)都提供了在没有帧指针的情况下编译 32 位代码的能力。 重要的是调用约定的实现是一致的。如果所有代码都希望在堆栈上传递参数,那很好,但被调用的代码最好同意这一点。同样,通过寄存器传递也可以,只是每个人都必须同意(至少在库接口(interface)级别,内部函数通常可以随心所欲)。

除此之外,请记住,两者之间的区别并不是真正的问题,因为每个进程都有自己的内存私有(private) View 。一个副作用是 32 位应用程序无法加载 64 位 dll,而 64 位应用程序无法加载 32 位 dll,因为进程要么具有 32 位代码段,要么具有 64 位代码部分。不能两者兼而有之。

关于64-bit - 为什么 x64 操作系统可以运行为 x86 机器编译的代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11812776/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com