Luke Blevins
Luke Blevins

Reputation: 49

x86 Intel Assembly Program Only Compiles In NASM

I noticed this simple x86 Intel Assembly program only compiles and runs on the NASM Assembler in Linux. I was curious regarding if I am able to compile a Windows Assembly program, using the MASM syntax, on Linux. (in NASM) If not, I would be curious about what limitations, or differences there are between the NASM and MASM syntax.

I am now aware of the differences between the two stated in the NASM documentation. (Available at http://www.nasm.us/doc/nasmdoc2.html#section-2.2) However, I am still confused in regards to the system interrupts on Windows. For example, Does Windows require the interrupts to be called in a different manner than Unix-based operating systems?

Finally, I need to know if there is a more efficient way to achieve the same result.

HelloWorld Assembly Program:

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

These are the errors displayed when assembling the file.

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 . . .

Upvotes: 3

Views: 1461

Answers (1)

Cody Gray
Cody Gray

Reputation: 244742

The code you have is designed to be assembled in NASM, which uses slightly different syntax compared to MASM (Microsoft's assembler). That's why you're getting the syntax errors. For example, while NASM does section .data and section .text, MASM does .data and .code, respectively. There are some other differences, too, but (A) making an exhaustive list is outside the scope of a single Stack Overflow answer, and (B) translating this code syntactically won't help you either, because…

The code you have is also written for Linux. You can tell because it is making system calls by invoking interrupt 80h (int 80h), which is the mechanism for system calls on 32-bit Linux. Windows does not make system calls this way; instead, you are expected to call an API function provided by the operating system. For example, on Linux, you do:

mov eax, 1
mov ebx, 0
int 80h

to exit the process. On Windows, you call the 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, which have done this (and a whole lot more) for you.

Note, however, that you only need to worry about all of this OS-specific stuff if you actually want to write real programs in assembly language. If you just want to learn how assembly language works, then this is unnecessary complexity. The basic arithmetic and bitwise operations that you do in assembly language work the same on all operating systems, so this is what you should focus on learning. To save yourself a lot of frustration, make sure that your tutorial/book matches the assembler and operating system you're actually using to write the code. If the online IDE works for you, and matches your tutorial, then stick with using that (it does, in this case, because it uses NASM running on Linux).

I should mention for completeness that you can even run NASM on Windows, which would save you the work of translating the syntax from NASM to MASM format. But, again, this won't help for the OS-specific stuff, like interrupts (int). So you'd end up massively rewriting the code anyway for Windows, which wouldn't really be helping you to learn anything other than Windows programming, and if you want to learn Windows programming, there's little point in doing it from assembly language. Do it from C, following the classic book (5th edition only). All of the API calls are exactly the same in both C and assembly language, since they're provided by the OS. Learning them from the context of C allows you to focus on learning the APIs, rather than dealing with the complexity of assembly language.

Upvotes: 3

Related Questions