Visual Studio C/C++ Project with MASM code produces error `error A2008: syntax error : .`
Visual Studio C/C++ Project with MASM code produces error `error A2008: syntax error : .`
我有一个 Visual Studio C/C++ 项目,其中只有一个程序集文件 main.asm
。在构建项目的过程中出现错误:
1>main.asm(5): error A2008: syntax error : .
1>main.asm(6): error A2008: syntax error : .
1>main.asm(7): error A2008: syntax error : .
1>main.asm(8): error A2008: syntax error : ,
1>main.asm(20): error A2008: syntax error : INVOKE
我的 main.asm 代码是:
; program 3.1
; sample Assembly program - MASM (32-bit)
.386 ; Line 5
.MODEL FLAT, stdcall ; Line 6
.STACK 4096 ; Line 7
ExitProcess PROTO, dwExitCode:DWORD ; Line 8
.data
sum DWORD 0
.code
_main PROC
mov eax, 25
mov ebx, 50
add ebx, ebx
mov sum, eax
INVOKE ExitProcess, 0 ; Line 20
_main ENDP
END
Visual Studio 的屏幕截图以及我的代码和错误:
为什么会出现这些错误,我该如何解决?
根据您在以 .MODEL
、.STACK
和 .386
开头的行中显示的错误,我只能推测您是为 64 位目标构建的,而不是比 32 位目标。您可能还收到了与 INVOKE
指令相关的错误。 None 这些指令受 64 位 MASM 支持,因此会产生错误。在 64 位代码中,模型总是被假定为平坦的,CDECL、STDCALL、THISCALL、FASTCALL 等的调用约定都是相同的,并遵循 Windows 64-bit Calling Convention.
你有两个选择:
构建 32 位应用程序。在 Visual Studio 作为菜单栏的一部分,有一个平台的下拉框。可以在工具栏中通过将 x64
更改为 x86
:
来调整平台
修改代码以使用 64 位代码。要构建 64 位,您必须将 INVOKE
替换为 CALL
,并且必须使用 Windows 64-bit calling convention。您可以删除 .STACK
、.MODEL
和 .386
指令。通过用 PROC
类型声明它们 EXTERN
来修改外部过程的定义。代码可能类似于:
; program 3.1
; sample Assembly program - MASM (64-bit)
extern ExitProcess:PROC
public mainCRTStartup
.data
sum DWORD 0
.code
mainCRTStartup PROC ; Use mainCRTStartup if making a CONSOLE app without
; any C/C++ files AND if you haven't overridden the
; ENTRY point in the Visual Studio Project.
sub rsp, 8+32 ; Align stack on 16 byte boundary and allocate 32 bytes
; of shadow space for call to ExitProcess. Shadow space
; is required for 64-bit Windows Calling Convention as
; is ensuring the stack is aligned on a 16 byte boundary
; at the point of making a call to a C library function
; or doing a WinAPI call.
mov eax, 25
mov ebx, 50
add ebx, ebx
mov sum, eax
xor ecx, ecx ; Set Error Code to 0 (RCX is 1st parameter)
call ExitProcess
mainCRTStartup ENDP
END
根据您创建的是 GUI 应用程序还是 CONSOLE 应用程序以及您的项目是否存在 C/C++ 文件,您的环境的入口点可能会有所不同。
与 32 位 Windows 代码不同,64 位调用约定中的函数名称不需要以下划线开头。
我有一个 Visual Studio C/C++ 项目,其中只有一个程序集文件 main.asm
。在构建项目的过程中出现错误:
1>main.asm(5): error A2008: syntax error : . 1>main.asm(6): error A2008: syntax error : . 1>main.asm(7): error A2008: syntax error : . 1>main.asm(8): error A2008: syntax error : , 1>main.asm(20): error A2008: syntax error : INVOKE
我的 main.asm 代码是:
; program 3.1
; sample Assembly program - MASM (32-bit)
.386 ; Line 5
.MODEL FLAT, stdcall ; Line 6
.STACK 4096 ; Line 7
ExitProcess PROTO, dwExitCode:DWORD ; Line 8
.data
sum DWORD 0
.code
_main PROC
mov eax, 25
mov ebx, 50
add ebx, ebx
mov sum, eax
INVOKE ExitProcess, 0 ; Line 20
_main ENDP
END
Visual Studio 的屏幕截图以及我的代码和错误:
为什么会出现这些错误,我该如何解决?
根据您在以 .MODEL
、.STACK
和 .386
开头的行中显示的错误,我只能推测您是为 64 位目标构建的,而不是比 32 位目标。您可能还收到了与 INVOKE
指令相关的错误。 None 这些指令受 64 位 MASM 支持,因此会产生错误。在 64 位代码中,模型总是被假定为平坦的,CDECL、STDCALL、THISCALL、FASTCALL 等的调用约定都是相同的,并遵循 Windows 64-bit Calling Convention.
你有两个选择:
构建 32 位应用程序。在 Visual Studio 作为菜单栏的一部分,有一个平台的下拉框。可以在工具栏中通过将
来调整平台x64
更改为x86
:修改代码以使用 64 位代码。要构建 64 位,您必须将
INVOKE
替换为CALL
,并且必须使用 Windows 64-bit calling convention。您可以删除.STACK
、.MODEL
和.386
指令。通过用PROC
类型声明它们EXTERN
来修改外部过程的定义。代码可能类似于:; program 3.1 ; sample Assembly program - MASM (64-bit) extern ExitProcess:PROC public mainCRTStartup .data sum DWORD 0 .code mainCRTStartup PROC ; Use mainCRTStartup if making a CONSOLE app without ; any C/C++ files AND if you haven't overridden the ; ENTRY point in the Visual Studio Project. sub rsp, 8+32 ; Align stack on 16 byte boundary and allocate 32 bytes ; of shadow space for call to ExitProcess. Shadow space ; is required for 64-bit Windows Calling Convention as ; is ensuring the stack is aligned on a 16 byte boundary ; at the point of making a call to a C library function ; or doing a WinAPI call. mov eax, 25 mov ebx, 50 add ebx, ebx mov sum, eax xor ecx, ecx ; Set Error Code to 0 (RCX is 1st parameter) call ExitProcess mainCRTStartup ENDP END
根据您创建的是 GUI 应用程序还是 CONSOLE 应用程序以及您的项目是否存在 C/C++ 文件,您的环境的入口点可能会有所不同。
与 32 位 Windows 代码不同,64 位调用约定中的函数名称不需要以下划线开头。