32 位 MASM 模式与 64 位有何不同?

Posted

技术标签:

【中文标题】32 位 MASM 模式与 64 位有何不同?【英文标题】:How does 32-bit MASM mode differ from 64-bit? 【发布时间】:2021-03-24 13:18:18 【问题描述】:

要使用 MASM 用 32 位汇编语言编写完整的程序,可以这样开始,

.686
.model flat,c
.stack 100h
.data
number sdword 5
.code
main proc
mov eax,number
ret
main endp
end main

而在 64 位模式下,代码编写为

.data
number sdword 5
.code
main proc
mov eax,number
ret
main endp
end

这些设置被设置为默认值,这导致在 64 位模式下组装时出现错误,不是因为平台设置为 Win32,而是默认入口点 mainCRTStartup。要解决此问题,必须在高级链接器选项中将其设置为 main

我的问题是,为什么在 32 位模式下不会遇到这样的问题,而 mainCRTStartup 入口点到底指的是什么?我的第二个问题是,为什么在 64 位模式下汇编我们省略了第一条指令行.686 .model flat,c .stack 100h 我们不必分配堆栈以及语言类型吗? 指令.686 表示,

为 Pentium Pro 处理器启用非特权指令的汇编。 (仅限 32 位 MASM。)

为什么在 64 位模式下不是这样?

【问题讨论】:

【参考方案1】:

32 位 MASM 可以在 16 位和 32 位可执行文件之间进行选择,具体取决于指令。构建 64 位代码时并非如此,因此相关的指令较少。

x86-64 ISA 保证支持 PPro 指令,因此无需启用它们。 (与 SSE / SSE2 相同)。您的代码在 64 位模式下运行这一事实意味着它们是可用的,就像 .model flat 中的 movzx 等 386 个功能一样。 但您在 MASM 中使用命令行选项而不是指令来选择

当您只想使用 AVX1 时,MASM 是否没有针对其他后续扩展(如 .haswell.bmi2)的指令来帮助您避免意外使用新指令(如 AVX2 vpermpd ymm0, ymm1, 0x01)?其他一些汇编程序确实具有类似的功能,例如 YASM 的 CPU 指令,或者 GNU 汇编程序可以让您限制功能。 (默认情况下,GAS 和 YASM/NASM 接受他们所知道的一切。)


x86-64 长模式也强制使用平面内存模型(CS.base = DS.base = ES.base = SS.base),因此无需选择内存模型。非平面内存分段只能在兼容模式下的 64 位内核下实现(如 32 位或 16 位保护模式的用户空间端)。 https://en.wikipedia.org/wiki/X86-64#Operating_modes

此外,MASM .model 也是假设 32 位模式与 16 位模式的代理,这很奇怪。其他汇编程序将其更正交地分开,例如 bits 16 / bits 32 / bits 64 以设置当前模式。 (但在 NASM 中,它不会更改输出文件格式;它只是让您将 64 位代码放入 32 位目标文件中,除非您正在编写一个 切换的内核,否则您不想这样做 模式。)


对于.stack,主线程堆栈的最大大小由链接器设置(使用/STACK 命令行选项),而不是汇编器。这取代了让汇编器将元数据放在.obj 文件中以供链接器查找的机制,或者它实际上工作的机制。 (AFAIK .stack 无论如何只对 16 位可执行文件很重要,甚至对 .model flat 也不重要。 您通常不希望在 32 位代码中使用 256 字节的微小堆栈)。

【讨论】:

MASM 没有指令 - VS2019 的 masm 指令的 list 说“没有”。它们确实有处理器指令,但它们都被标记为“仅限 32 位”。 声明 x86-64 长模式强制使用平面内存模型,是否也强制不使用任何高级指令,例如 .if .else .repeat 等? @EnthusiastiC x64 MASM 不支持任何“更高级别”指令,例如 .if.whileINVOKE。它们需要更新以生成适当的 64 位指令,而微软从不打扰。就像 Peter Cordes 所说的那样,像这样的高级指令违背了编写汇编代码的全部目的。如果您想要一种高级编程语言,那么您应该使用高级编程语言。例如,C 编译器将为其函数调用和 ifwhile 语句生成比 MASM 为 INVOKE .if.while 生成的更好的代码。 @EnthusiastiC 这是一个单独的问题,这里已经有人问过了:***.com/questions/29390886/… 因此,总而言之,微软没有更新 32 位高级指令以便能够在较新的 64 位版本中实现它们,因为它们毫无意义,因为汇编会浪费.此外,64 位版本与 32 位版本不同,它无法像 .model flat, c 中的 32 位那样指定语言类型。

以上是关于32 位 MASM 模式与 64 位有何不同?的主要内容,如果未能解决你的问题,请参考以下文章

电脑32位和64位有啥区别 电脑32位和64位的区别

电脑32位和64位有啥区别

Win7 32位和64位有啥区别?装哪个好?

Win7系统32位和64位有什么区别?

32位程序下调用64位函数——进程32位模式与64位模式切换

当我们在 Visual Studio SSIS 项目中点击调试按钮时——它是在 32 位还是 64 位模式下运行——32 位提供程序是不是与 64 位运行模式兼容?