x86 英特尔汇编程序仅在 NASM 中编译
x86 Intel Assembly Program Only Compiles In NASM
我注意到这个简单的 x86 Intel 汇编程序只能在 Linux 中的 NASM 汇编器上编译和运行。我很好奇我是否能够在 Linux 上使用 MASM 语法编译一个 Windows 汇编程序。 (在 NASM 中)如果不是,我想知道 NASM 和 MASM 语法之间有哪些限制或差异。
我现在知道 NASM 文档中所述的两者之间的区别。 (在 http://www.nasm.us/doc/nasmdoc2.html#section-2.2 上可用)但是,我仍然对 Windows 上的系统中断感到困惑。例如,Windows 是否需要以与基于 Unix 的操作系统不同的方式调用中断?
最后,我想知道是否有更有效的方法来实现相同的结果。
HelloWorld 程序集:
section .data ;Constant Data Section
userMsg db 'What is your name?' ;Request Name Input
lengthMsg equ $-userMsg ;Set length of request
returnMsg db 'Hello there, ' ;Return Message
lengthRet equ $-returnMsg ;Set length of returned message
section .bss
number resb 5
section .text
global _start
_start:
mov eax, 4 ;Print first message to screen
mov ebx, 1
mov ecx, userMsg
mov edx, lengthMsg
int 80h
mov eax, 3
mov ebx, 2
mov ecx, number
mov edx, 5
int 80h
mov eax, 4
mov ebx, 1
mov ecx, returnMsg
mov edx, lengthRet
int 80h
mov eax, 4
mov ebx, 1
mov ecx, number
mov edx, 5
int 80h
mov eax, 1
mov ebx, 0
int 80h
这些是汇编文件时显示的错误。
Microsoft (R) Macro Assembler Version 6.14.8444
Copyright (C) Microsoft Corp 1981-1997. All rights reserved.
Assembling: C:\Projects\theapp.asm
C:\Projects\theapp.asm(1) : error A2008: syntax error : section
C:\Projects\theapp.asm(2) : error A2034: must be in segment block
C:\Projects\theapp.asm(3) : error A2034: must be in segment block
C:\Projects\theapp.asm(5) : error A2034: must be in segment block
C:\Projects\theapp.asm(6) : error A2034: must be in segment block
C:\Projects\theapp.asm(8) : error A2008: syntax error : section
C:\Projects\theapp.asm(9) : error A2008: syntax error : number
C:\Projects\theapp.asm(11) : error A2008: syntax error : section
C:\Projects\theapp.asm(12) : error A2008: syntax error : global
C:\Projects\theapp.asm(15) : error A2034: must be in segment block
C:\Projects\theapp.asm(16) : error A2085: instruction or register not accepted in current CPU mode
C:\Projects\theapp.asm(17) : error A2085: instruction or register not accepted in current CPU mode
C:\Projects\theapp.asm(18) : error A2085: instruction or register not accepted in current CPU mode
C:\Projects\theapp.asm(19) : error A2085: instruction or register not accepted in current CPU mode
C:\Projects\theapp.asm(20) : error A2034: must be in segment block
C:\Projects\theapp.asm(22) : error A2085: instruction or register not accepted in current CPU mode
C:\Projects\theapp.asm(23) : error A2085: instruction or register not accepted in current CPU mode
C:\Projects\theapp.asm(24) : error A2085: instruction or register not accepted in current CPU mode
C:\Projects\theapp.asm(25) : error A2085: instruction or register not accepted in current CPU mode
C:\Projects\theapp.asm(26) : error A2034: must be in segment block
C:\Projects\theapp.asm(28) : error A2085: instruction or register not accepted in current CPU mode
C:\Projects\theapp.asm(29) : error A2085: instruction or register not accepted in current CPU mode
C:\Projects\theapp.asm(30) : error A2085: instruction or register not accepted in current CPU mode
C:\Projects\theapp.asm(31) : error A2085: instruction or register not accepted in current CPU mode
C:\Projects\theapp.asm(32) : error A2034: must be in segment block
C:\Projects\theapp.asm(34) : error A2085: instruction or register not accepted in current CPU mode
C:\Projects\theapp.asm(35) : error A2085: instruction or register not accepted in current CPU mode
C:\Projects\theapp.asm(36) : error A2085: instruction or register not accepted in current CPU mode
C:\Projects\theapp.asm(37) : error A2085: instruction or register not accepted in current CPU mode
C:\Projects\theapp.asm(38) : error A2034: must be in segment block
C:\Projects\theapp.asm(40) : error A2085: instruction or register not accepted in current CPU mode
C:\Projects\theapp.asm(41) : error A2085: instruction or register not accepted in current CPU mode
C:\Projects\theapp.asm(42) : error A2034: must be in segment block
C:\Projects\theapp.asm(45) : error A2088: END directive required at end of file
_
Assembly Error
Press any key to continue . . .
您的代码设计为在 NASM 中汇编,与 MASM(Microsoft 的汇编程序)相比,它使用的语法略有不同。这就是您收到语法错误的原因。例如,虽然 NASM 执行 section .data
和 section .text
,但 MASM 分别执行 .data
和 .code
。还有一些其他差异,但是 (A) 列出详尽的列表超出了单个 Stack Overflow 答案的范围,并且 (B) 从句法上翻译这段代码对你也没有帮助,因为……
您的代码也是为Linux编写的。您可以看出,因为它正在通过调用中断 80h (int 80h
) 进行系统调用,这是 32 位系统调用的机制 Linux。 Windows 不会这样进行系统调用;相反,您应该调用操作系统提供的 API 函数。例如,在 Linux 上,您执行:
mov eax, 1
mov ebx, 0
int 80h
退出进程。在 Windows,你打电话给 ExitProcess
API function, which is exported by the kernel32.dll library that ships with the operating system. The prototypes for these OS API functions are provided with the Windows SDK in a C header (Windows.h
). You can use a tool like h2inc.exe
to convert those to assembly-language prototypes, or you can just write the necessary prototypes yourself by looking at the documentation for the function. Or, lots of people use the MASM32 libraries,它已经为你完成了这个(以及更多)。
但是请注意,如果您真的想用汇编语言编写真正的程序,您只需要担心所有这些 OS 特定的东西。如果您只是想学习 汇编语言是如何工作的,那么这是不必要的复杂性。您在汇编语言中执行的基本算术和按位运算在所有操作系统上都相同,因此这是您应该重点学习的内容。为了让自己避免很多挫折,请确保您的 tutorial/book 与您实际用于编写代码的汇编程序 和 操作系统相匹配。如果在线 IDE 适合你,并且与你的教程相匹配,那么坚持使用它(在这种情况下,它确实如此,因为它在 Linux 上使用 NASM 运行ning ).
为了完整起见,我应该提到你甚至可以在 Windows 上 运行 NASM,这将节省你将语法从 NASM 转换为 MASM 格式的工作.但是,同样,这对 OS 特定的东西没有帮助,比如中断 (int
)。所以你最终会大量重写 Windows 的代码,这对你学习 Windows 编程以外的任何东西都没有真正的帮助,如果你想学习 Windows 编程,用汇编语言做这件事毫无意义。按照 the classic book (5th edition only),从 C 开始。所有 API 调用在 C 语言和汇编语言中 完全相同 ,因为它们是由 OS 提供的。从 C 的上下文中学习它们可以让您专注于学习 API,而不是处理汇编语言的复杂性。
我注意到这个简单的 x86 Intel 汇编程序只能在 Linux 中的 NASM 汇编器上编译和运行。我很好奇我是否能够在 Linux 上使用 MASM 语法编译一个 Windows 汇编程序。 (在 NASM 中)如果不是,我想知道 NASM 和 MASM 语法之间有哪些限制或差异。
我现在知道 NASM 文档中所述的两者之间的区别。 (在 http://www.nasm.us/doc/nasmdoc2.html#section-2.2 上可用)但是,我仍然对 Windows 上的系统中断感到困惑。例如,Windows 是否需要以与基于 Unix 的操作系统不同的方式调用中断?
最后,我想知道是否有更有效的方法来实现相同的结果。
HelloWorld 程序集:
section .data ;Constant Data Section
userMsg db 'What is your name?' ;Request Name Input
lengthMsg equ $-userMsg ;Set length of request
returnMsg db 'Hello there, ' ;Return Message
lengthRet equ $-returnMsg ;Set length of returned message
section .bss
number resb 5
section .text
global _start
_start:
mov eax, 4 ;Print first message to screen
mov ebx, 1
mov ecx, userMsg
mov edx, lengthMsg
int 80h
mov eax, 3
mov ebx, 2
mov ecx, number
mov edx, 5
int 80h
mov eax, 4
mov ebx, 1
mov ecx, returnMsg
mov edx, lengthRet
int 80h
mov eax, 4
mov ebx, 1
mov ecx, number
mov edx, 5
int 80h
mov eax, 1
mov ebx, 0
int 80h
这些是汇编文件时显示的错误。
Microsoft (R) Macro Assembler Version 6.14.8444
Copyright (C) Microsoft Corp 1981-1997. All rights reserved.
Assembling: C:\Projects\theapp.asm
C:\Projects\theapp.asm(1) : error A2008: syntax error : section
C:\Projects\theapp.asm(2) : error A2034: must be in segment block
C:\Projects\theapp.asm(3) : error A2034: must be in segment block
C:\Projects\theapp.asm(5) : error A2034: must be in segment block
C:\Projects\theapp.asm(6) : error A2034: must be in segment block
C:\Projects\theapp.asm(8) : error A2008: syntax error : section
C:\Projects\theapp.asm(9) : error A2008: syntax error : number
C:\Projects\theapp.asm(11) : error A2008: syntax error : section
C:\Projects\theapp.asm(12) : error A2008: syntax error : global
C:\Projects\theapp.asm(15) : error A2034: must be in segment block
C:\Projects\theapp.asm(16) : error A2085: instruction or register not accepted in current CPU mode
C:\Projects\theapp.asm(17) : error A2085: instruction or register not accepted in current CPU mode
C:\Projects\theapp.asm(18) : error A2085: instruction or register not accepted in current CPU mode
C:\Projects\theapp.asm(19) : error A2085: instruction or register not accepted in current CPU mode
C:\Projects\theapp.asm(20) : error A2034: must be in segment block
C:\Projects\theapp.asm(22) : error A2085: instruction or register not accepted in current CPU mode
C:\Projects\theapp.asm(23) : error A2085: instruction or register not accepted in current CPU mode
C:\Projects\theapp.asm(24) : error A2085: instruction or register not accepted in current CPU mode
C:\Projects\theapp.asm(25) : error A2085: instruction or register not accepted in current CPU mode
C:\Projects\theapp.asm(26) : error A2034: must be in segment block
C:\Projects\theapp.asm(28) : error A2085: instruction or register not accepted in current CPU mode
C:\Projects\theapp.asm(29) : error A2085: instruction or register not accepted in current CPU mode
C:\Projects\theapp.asm(30) : error A2085: instruction or register not accepted in current CPU mode
C:\Projects\theapp.asm(31) : error A2085: instruction or register not accepted in current CPU mode
C:\Projects\theapp.asm(32) : error A2034: must be in segment block
C:\Projects\theapp.asm(34) : error A2085: instruction or register not accepted in current CPU mode
C:\Projects\theapp.asm(35) : error A2085: instruction or register not accepted in current CPU mode
C:\Projects\theapp.asm(36) : error A2085: instruction or register not accepted in current CPU mode
C:\Projects\theapp.asm(37) : error A2085: instruction or register not accepted in current CPU mode
C:\Projects\theapp.asm(38) : error A2034: must be in segment block
C:\Projects\theapp.asm(40) : error A2085: instruction or register not accepted in current CPU mode
C:\Projects\theapp.asm(41) : error A2085: instruction or register not accepted in current CPU mode
C:\Projects\theapp.asm(42) : error A2034: must be in segment block
C:\Projects\theapp.asm(45) : error A2088: END directive required at end of file
_
Assembly Error
Press any key to continue . . .
您的代码设计为在 NASM 中汇编,与 MASM(Microsoft 的汇编程序)相比,它使用的语法略有不同。这就是您收到语法错误的原因。例如,虽然 NASM 执行 section .data
和 section .text
,但 MASM 分别执行 .data
和 .code
。还有一些其他差异,但是 (A) 列出详尽的列表超出了单个 Stack Overflow 答案的范围,并且 (B) 从句法上翻译这段代码对你也没有帮助,因为……
您的代码也是为Linux编写的。您可以看出,因为它正在通过调用中断 80h (int 80h
) 进行系统调用,这是 32 位系统调用的机制 Linux。 Windows 不会这样进行系统调用;相反,您应该调用操作系统提供的 API 函数。例如,在 Linux 上,您执行:
mov eax, 1
mov ebx, 0
int 80h
退出进程。在 Windows,你打电话给 ExitProcess
API function, which is exported by the kernel32.dll library that ships with the operating system. The prototypes for these OS API functions are provided with the Windows SDK in a C header (Windows.h
). You can use a tool like h2inc.exe
to convert those to assembly-language prototypes, or you can just write the necessary prototypes yourself by looking at the documentation for the function. Or, lots of people use the MASM32 libraries,它已经为你完成了这个(以及更多)。
但是请注意,如果您真的想用汇编语言编写真正的程序,您只需要担心所有这些 OS 特定的东西。如果您只是想学习 汇编语言是如何工作的,那么这是不必要的复杂性。您在汇编语言中执行的基本算术和按位运算在所有操作系统上都相同,因此这是您应该重点学习的内容。为了让自己避免很多挫折,请确保您的 tutorial/book 与您实际用于编写代码的汇编程序 和 操作系统相匹配。如果在线 IDE 适合你,并且与你的教程相匹配,那么坚持使用它(在这种情况下,它确实如此,因为它在 Linux 上使用 NASM 运行ning ).
为了完整起见,我应该提到你甚至可以在 Windows 上 运行 NASM,这将节省你将语法从 NASM 转换为 MASM 格式的工作.但是,同样,这对 OS 特定的东西没有帮助,比如中断 (int
)。所以你最终会大量重写 Windows 的代码,这对你学习 Windows 编程以外的任何东西都没有真正的帮助,如果你想学习 Windows 编程,用汇编语言做这件事毫无意义。按照 the classic book (5th edition only),从 C 开始。所有 API 调用在 C 语言和汇编语言中 完全相同 ,因为它们是由 OS 提供的。从 C 的上下文中学习它们可以让您专注于学习 API,而不是处理汇编语言的复杂性。