使用 g++ -march=x86-64 构建的代码可以在 32 位操作系统上运行吗? [英] Can code built with g++ -march=x86-64 run on a 32-bit Operating System?

查看:52
本文介绍了使用 g++ -march=x86-64 构建的代码可以在 32 位操作系统上运行吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想我对 x86-64/i686 架构和 32 位/64 位操作系统感到困惑.

I think I'm confused between x86-64/i686 architectures and 32-bit/64-bit operating systems.

如果我在 32 位操作系统(例如 Ubuntu 14.04)上使用 g++ 构建应用程序,则 -m64 不是有效选项,我无法构建64 位二进制.然而,g++ 并没有抱怨使用 -march=x86-64.(硬件为酷睿 i7.)

If I build an app with g++ on a 32-bit operating system (e.g. Ubuntu 14.04) then -m64 is not a valid option and I can't build 64-bit binary. However, g++ does not complain about using -march=x86-64. (Hardware is Core i7.)

然后,如果我在 64 位操作系统(例如 Ubuntu 20.04)上构建,我可以在 -m32-m64 之间切换并构建 32 位或 64-bit 二进制文件.

Then, if I build on a 64-bit OS (e.g. Ubuntu 20.04), I can switch between -m32 and -m64 and build 32-bit or 64-bit binaries.

所以,我的理解是...

So, my understanding is...

-m32-m64 规定了我可以在哪些操作系统上使用二进制文件.(包括在 64 位操作系统上使用的 32 位二进制文​​件以及适当的库)

-m32 and -m64 dictates which operating systems I can use the binaries on. (Including 32-bit binaries used on 64-bit OS with appropriate libraries)

并且 -march 定义将用于代码生成的指令集 - 无论它注定要运行的操作系统如何.

And -march defines which instruction set will be used for code generation - regardless of the operating system it's destined to run on.

所以我的主要问题是...

So my primary question is...

鉴于我可以使用 -m32 -march=x86-64 在 32 位操作系统上构建和运行二进制文件,这是否意味着 x86-64 指令可以 在 32 位操作系统上使用?

Given that I can use -m32 -march=x86-64 for building and running a binary on a 32-bit OS, does that mean x86-64 instructions can be used on a 32-bit OS?

推荐答案

不,64 位指令不能在 32 位操作系统下使用(甚至不能在 64 位内核下的 32 位用户空间中使用)),这不是 -march=x86-64 的意思.

No, 64-bit instructions can't be used under a 32-bit OS (or even in 32-bit user-space under a 64-bit kernel), and that's not what -march=x86-64 means.

-march=x86-64 表示目标 CPU 支持 x86-64 保证的 ISA 扩展基线集:SSE2、P6 功能,如 CMOV、CPUID、RDTSC 等.但是如果没有 -m64,代码仍然可以在 32 位模式下工作.

-march=x86-64 means the target CPU supports the baseline set of ISA extensions that x86-64 guarantees: SSE2, P6 features like CMOV, CPUID, RDTSC, and so on. But without -m64, the code will still work in 32-bit mode.

(对于 x86-64 的目标 ISA,它们本身并不是扩展".但我们仍然通常说 x86-64 意味着 SSE 和 SSE2,因为这是对那些操作的指令进行分类的方便方法XMM 寄存器.如果我们将 x86-64 本身视为 x86 的扩展,这很有意义.)

(For a target ISA of x86-64, they aren't "extensions" per-se. But we still generally say that x86-64 implies SSE and SSE2 because that's a handy way to categorize those instructions that operate on XMM registers. That makes sense if we think of x86-64 itself as an extension to x86.)

所以 -march=x86-64-march=k8-march=nocona 非常相似(特定于早期的 x86-64CPU).就像这些选项一样,它对 -m32 完全有效,并不意味着制作 64 位代码.GCC 仍然知道(来自 -m32)它的目标是 32 位模式(保护或兼容模式),而不是 64 位长模式.

So -march=x86-64 is very similar to -march=k8 or -march=nocona (specific early x86-64 CPUs). Just like those options, it's fully valid with -m32 and doesn't imply making 64-bit code. GCC still knows (from -m32) that it's targeting 32-bit mode (protected or compat mode), not 64-bit long mode.

因为这些模式使用不兼容的机器代码格式,所以它完全不像 16 位到 32 位的转换,您可能期望 -march=i386 同时制作 16 位代码让编译器使用 32 位寄存器.在 x86-64 中,64 位寄存器只能用于长模式,不能用于兼容模式或遗留模式的任何子模式(例如保护模式).请参阅 https://en.wikipedia.org/wiki/X86-64#Operating_modes

Since those modes use incompatible machine-code formats, it's not at all like the 16-bit to 32-bit transition where you might expect -march=i386 while making 16-bit code to let the compiler use 32-bit registers. In x86-64, 64-bit registers can only be used in long mode, not compat mode or any sub-mode of legacy mode (such as protected mode). See https://en.wikipedia.org/wiki/X86-64#Operating_modes

这里的关键点是,在兼容模式下(在 64 位内核下),32 位进程无法执行在保护模式下(在 32 位内核下)无法执行的任何操作.x86-64 没有为 32 位进程提供在 64 位内核下运行的优势.(除了将远 jmp 转换为 64 位代码段,但大多数操作系统不支持这一点,编译器肯定不会发出代码来做到这一点.当然使用完整的 4GB 地址空间,但就实际的机器代码指令什么都没有.)因此,没有任何您希望编译器使用的功能只能在 64 位内核下以 32 位模式运行.

The key point here is that there's nothing a 32-bit process can do in compat mode (under a 64-bit kernel) that it can't do in protected mode (under a 32-bit kernel). x86-64 doesn't provide a way for 32-bit processes to take advantage of running under a 64-bit kernel. (Except by making a far jmp to a 64-bit code segment, but most OSes don't support this and compilers are definitely won't emit code to do it. And of course using the full 4GB of address space, but in terms of actual machine code instructions there's nothing.) So there aren't any features you'd ever want to let a compiler use that could only work in 32-bit mode under a 64-bit kernel.

TL:DR:-m32 -march=x86-64 可以解释为通用 x86-64 CPU 的目标兼容/保护模式".

TL:DR: -m32 -march=x86-64 could be interpreted as "target compat/protected mode of a generic x86-64 CPU".

在实践中,它实际上只是意味着启用这组 ISA 扩展",并且 该名称对于 GCC 而言并不比 -march=foobarbaz- 更有意义mtune=intel,它只是一个用于调整和 ISA 扩展设置表的文本字符串.

In practice it really just means "enable this set of ISA extensions", and the name isn't any more meaningful to GCC than -march=foobarbaz or -mtune=intel, it's just a text string for a table of tuning and ISA-extension settings.

这篇关于使用 g++ -march=x86-64 构建的代码可以在 32 位操作系统上运行吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆