How does 32-bit MASM mode differ from 64-bit?

十年热恋 提交于 2021-01-28 11:15:06

问题


To write a complete program in 32-bit assembly language using MASM one may start like this,

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

whereas in 64-bit mode the code is written as

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

The settings are set to default which led to occur an error while assembling in a 64-bit mode not because the platform is set to Win32, but instead the default entry point mainCRTStartup. To fix the problem it must be set to main in Advanced Linker options.

My question is, why encountering such a problem not happening in 32-bit mode, and what does the mainCRTStartup entry point referring to anyway? My second question is, why assembling in the 64-bit mode we omit the first directive lines .686 .model flat,c .stack 100h don't we have to allocate the stack, as well as the language type? The directive .686 indicates to,

Enables assembly of nonprivileged instructions for the Pentium Pro processor. (32-bit MASM only.)

why it's not the case in the 64-bit mode?


回答1:


32-bit MASM had a choice between 16-bit and 32-bit executables, depending on the directives. This is not the case when building 64-bit code, so fewer directives are relevant.

The x86-64 ISA guarantees that PPro instructions are supported so there's no need to enable them. (Same for SSE / SSE2). The fact that your code is running in 64-bit mode means they're available, just like 386 features like movzx in .model flat. But you choose that with command-line options, not directives, in MASM.

Does MASM not have directives for other later extensions like .haswell or .bmi2 to help you avoid using newer instructions by accident, like AVX2 vpermpd ymm0, ymm1, 0x01 when you only meant to use AVX1? Some other assemblers do have features like that, such as YASM's CPU directive, or the GNU assembler can let you restrict features. (By default GAS and YASM/NASM accept everything they knows about.)


x86-64 long mode also forces a flat memory model (CS.base = DS.base = ES.base = SS.base) so there's no need to choose a memory model. Non-flat memory segmentation is only possible under a 64-bit kernel in compat mode (like the user-space side of 32-bit or 16-bit protected mode). https://en.wikipedia.org/wiki/X86-64#Operating_modes

Also, MASM .model was also a proxy for assuming 32-bit mode vs. 16-bit mode, which was weird. Other assemblers separate this more orthogonally, like bits 16 / bits 32 / bits 64 to set the current mode. (But in NASM that doesn't change the output file format; that just lets you put 64-bit code into a 32-bit object file which you don't want to do unless you're writing a kernel that switches modes.)


For .stack, the max size of the main-thread stack is set by the linker (with the /STACK command-line option), not the assembler. That replaces the mechanism of having the assembler put metadata in the .obj file for the linker to find, or however it actually worked. (AFAIK .stack only ever mattered for 16-bit executables anyway, not even for .model flat. You wouldn't usually want a tiny 256-byte stack in 32-bit code).



来源:https://stackoverflow.com/questions/65279900/how-does-32-bit-masm-mode-differ-from-64-bit

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!