2
votes

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 . . .
1
your code is NASM, not MASM. The code you are showing is also Linux specific (int 80h system calls and numbers) and wouldn't work with Windows even if you had managed to assemble it. The online link you are using is also using NASM and is running on a Linux backend so that is why that works.Michael Petch
The online compiler is NASM, you're trying to use MASM. They're very differentSami Kuhmonen
Not VERY different, actually it would take just few changes (from the point of view of experienced x86 asm programmer) to make it compilable in MASM, but it would still not work under windows, so no point in doing that. .. Anything platform specific, like OS/service calls, will not work on different platform, but the CPU instructions, way how you write arithmetic and algorithms, etc... is same. So if you have 64b linux tutorial, just follow it on that online IDE, but that one doesn't have any working debugger, which is huge drawback. So you may even consider installing some linux into VM.Ped7g

1 Answers

2
votes

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.