x86英特尔汇编程序仅在NASM中编译

时间:2017-07-20 18:38:57

标签: assembly x86 nasm masm

我注意到这个简单的x86英特尔汇编程序只能编译并运行在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 . . .

1 个答案:

答案 0 :(得分:2)

您拥有的代码旨在以NASM汇编,与MASM(Microsoft的汇编程序)相比,它使用的语法略有不同。这就是您获取语法错误的原因。例如,当NASM执行section .datasection .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函数,该函数由操作系统附带的kernel32.dll库导出。这些OS API函数的原型随C头(Windows.h)中的Windows SDK一起提供。您可以使用h2inc.exe之类的工具将它们转换为汇编语言原型,或者您可以通过查看函数的文档自己编写必要的原型。或者,很多人使用MASM32 libraries,为你做了这个(还有更多)。

但是,请注意,如果您真的想用汇编语言编写真正的程序,那么您只需要担心所有这些特定于操作系统的内容。如果您只是想学习汇编语言的工作原理,那么这就是不必要的复杂性。您在汇编语言中执行的基本算术和按位运算在所有操作系统上的工作方式相同,因此您应该专注于学习。为了节省很多挫折感,请确保您的教程/书籍与您实际用于编写代码的汇编程序操作系统相匹配。如果在线IDE适合您,并且与您的教程相匹配,那么坚持使用它(在这种情况下,因为它使用在Linux上运行的NASM)。

我应该提一下,你甚至可以在Windows上运行NASM,这将节省你将语法从NASM翻译成MASM格式的工作。但是,同样,这对于特定于操作系统的内容(例如中断(int)也没有帮助。因此,无论如何,您最终都会为Windows大量重写代码,除了Windows编程之外,这并不能帮助您学习任何其他内容,如果您想学习Windows编程,那么还有一点点用汇编语言来做。在the classic book (5th edition only)之后从C做。所有API调用在C语言和汇编语言中都完全相同,因为它们是由操作系统提供的。从C语境中学习它们可以让你专注于学习API,而不是处理汇编语言的复杂性。