简体   繁体   English

32 位和 64 位汇编程序之间的区别?

[英]Difference between 32bit and 64bit Assembler Programs?

As far as I noticed a 32bit program uses the FLAT memory model and the 64bit also.据我所知,32 位程序使用 FLAT 内存模型,也使用 64 位。 Using the 32bit program one has only 4GB to address and using 64bit (rcx for example) makes it possible to saturate the 40 to 48 address bits modern CPU provide and address even more.使用 32 位程序只有 4GB 可寻址,而使用 64 位(例如 rcx)可以使现代 CPU 提供的 40 到 48 个地址位饱和并寻址更多。

So beside this and some additional control registers that a 32bit processor does not has, I ask myself if it is possible to run 32bit code in linux flawlessly.所以除了这个和一些 32 位处理器没有的额外控制寄存器,我问自己是否有可能在 linux 中完美地运行 32 位代码。

I mean must every C code I execute be 64bit for instance?我的意思是我执行的每个 C 代码都必须是 64 位的吗?

I can understand that since C builds upon a stack frame and base pointer pushing a 32bit base pointer on stack my introduce problems where the stack pointer is 64bit and one might access the pop and push op codes in 32 bit fashion.我可以理解,由于 C 建立在堆栈帧和基指针上,将 32 位基指针推送到堆栈上,因此我引入了堆栈指针为 64 位并且可能以 32 位方式访问 pop 和 push 操作代码的问题。

So what are the difference and is it possible to actually run 32bit code when running a 64bit Linux kernel?那么有什么区别,在运行 64 位 Linux 内核时是否可以实际运行 32 位代码?

[Update] [更新]

To state the scenario clear I am running a 64bit program and load a ELF64 file into memory map everything and call the method directly.为了清楚地说明场景,我正在运行一个 64 位程序并将 ELF64 文件加载到内存映射所有内容中并直接调用该方法。 The idea is to generate asm code dynamically.这个想法是动态生成 asm 代码。

The main difference between them is the different calling conventions.它们之间的主要区别在于不同的调用约定。 On 32bit there are several types: __stdcall, __fastcall, ...在 32 位上有几种类型:__stdcall、__fastcall、...

On 64bit (x64) there's only one (on Windows® platforms, about others I don't know) And it has some requirements, which are very different to 32bit.在 64 位 (x64) 上只有一个(在 Windows® 平台上,关于其他我不知道)而且它有一些要求,这与 32 位非常不同。 More on https://future2048.blogspot.com Note that ARM and IA64 (Itanium) also are different Encodings as x64 (Intel64/AMD64)更多关于https://future2048.blogspot.com请注意,ARM 和 IA64 (Itanium) 也是与 x64 (Intel64/AMD64) 不同的编码

And you have 8 more general registers r8..r15, with sub registers r8d..r15d, r8w..r15w, r8b..r15b For the SIMD-based code also 8 additional registers xmm8..xmm15 are present.您还有 8 个通用寄存器 r8..r15,以及子寄存器 r8d..r15d、r8w..r15w、r8b..r15b 对于基于 SIMD 的代码,还有 8 个额外的寄存器 xmm8..xmm15。

The exception handling is data-based on 64bit;异常处理是基于数据的64bit; on 32bit it was code-based.在 32 位上,它是基于代码的。 So on 64bit for unwinding exceptions no longer instructions are used to build the exception frame.因此,在 64 位上用于展开异常不再使用指令来构建异常帧。 The exceptiom handling is completely data-based so that no additional instructions are required to try/catch.异常处理完全基于数据,因此不需要额外的指令来尝试/捕获。

The memory limit of 2GB on 32bit apps (or with /LARGEADDRESSAWARE 3GB on an app on 32bit Win OS, or 4GB on 64bit Win OS) is now much larger More on https://msdn.microsoft.com/en-us/library/windows/desktop/aa366778(v=vs.85).aspx 32 位应用程序上的 2GB 内存限制(或在 32 位 Win OS 上的应用程序上使用 /LARGEADDRESSAWARE 3GB,或在 64 位 Win OS 上使用 4GB)现在要大得多。 /windows/desktop/aa366778(v=vs.85).aspx

And of course, the general purpose registers have 64bit width instead of 32bit.当然,通用寄存器的宽度是 64 位而不是 32 位。 So any integer calculation can process values bigger than the 32bit limit of 0..4294967296.因此,任何整数计算都可以处理大于 32 位限制 0..4294967296 的值。 (signed -2147483648..+2147483647) (签名-2147483648..+2147483647)

Also reading and storing memory with a simple MOV instruction can read and write a QWORD (64bit) at once;用简单的MOV指令读取和存储内存可以一次读写一个QWORD(64位); on 32bit that only could write a DWORD (32bit).在 32 位上只能写一个 DWORD(32 位)。

Some instructions have been removed: PUSHA + POPA disappeared.删除了一些说明:PUSHA + POPA 消失了。 And one Encoding form of INC/DEC is now used as REX-Byte prefix Encoding. INC/DEC 的一种编码形式现在用作 REX-Byte 前缀编码。

Some 32 bit code will work in a 64 bit environment without modification.某些 32 位代码无需修改即可在 64 位环境中运行。 However, in general, functions won't work because the calling conventions are probably different (depends on the architecture).但是,一般来说,函数将不起作用,因为调用约定可能不同(取决于体系结构)。 Depending on the program, you could write some glue to convert arguments to the calling convention you want.根据程序,您可以编写一些胶水将参数转换为您想要的调用约定。 So you can't just link a 32-bit library into your 64-bit application.因此,您不能仅将 32 位库链接到 64 位应用程序。

However, if your entire application is 32-bit, you will probably be able to run it just fine.但是,如果您的整个应用程序是 32 位的,您可能能够很好地运行它。 The word size of the kernel doesn't really matter.内核的字大小并不重要。 Popular operating systems all support running 32-bit code with a 64-bit kernel: Linux, OS X, and Windows support this.流行的操作系统都支持使用 64 位内核运行 32 位代码:Linux、OS X 和 Windows 支持这一点。

In short: you can run 32-bit applications on a 64-bit system but you can't mix 32-bit and 64-bit code in the same application (barring deep wizardry).简而言之:您可以在 64 位系统上运行 32 位应用程序,但您不能在同一个应用程序中混合 32 位和 64 位代码(除非有深厚的魔法)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM