【问题标题】:x86 Intel Assembly Program Only Compiles In NASMx86 Intel 汇编程序仅在 NASM 中编译
【发布时间】:2017-12-26 15:03:52
【问题描述】:

我注意到这个简单的 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。您显示的代码也是 Linux 特定的(int 80h 系统调用和数字),即使您设法组装它也不能与 Windows 一起使用。您正在使用的在线链接也使用 NASM 并且在 Linux 后端上运行,这就是它起作用的原因。
  • 在线编译器是 NASM,您正在尝试使用 MASM。它们非常不同
  • 没什么不同,实际上只需要进行一些更改(从经验丰富的 x86 asm 程序员的角度来看)就可以在 MASM 中编译,但它仍然无法在 Windows 下工作,所以没有意义在这样做。 .. 任何特定于平台的东西,比如操作系统/服务调用,都不能在不同的平台上工作,但是 CPU 指令、你编写算术和算法的方式等等......都是一样的。因此,如果您有 64b 的 linux 教程,只需在该在线 IDE 上进行操作,但该 IDE 没有任何可用的调试器,这是一个巨大的缺点。所以你甚至可以考虑在 VM 中安装一些 linux。

标签: assembly x86 nasm masm


【解决方案1】:

您拥有的代码被设计为在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,而不是处理汇编语言的复杂性。

【讨论】:

  • @duke 是的,引导加载程序可以用汇编语言编写,而且并不难。网上有很多资源讨论如何编写它们。请参阅this tutorialthis entire website。 Michael Petch 还在 Stack Overflow 上写了许多关于引导加载程序的精彩答案;阅读一些his answers 本身就是一个有用的教程。
  • 至于内核和操作系统,这有点困难,但当然可以用汇编或 C 语言来完成,随你喜欢。在踏上这段旅程之前,请确保您很好地学习了 C 语言。出于显而易见的原因,用 C 语言编写操作系统并不是一个好的第一个项目。尤其是如果您的背景主要是 Java,因为您将有一种无法满足的对内存泄漏代码的渴望。 :-) 除了关于操作系统的 Tannenbaum 书之外,我没有任何具体的资源可以推荐。 MikeOS 是一个简单的开源操作系统,由第一个编写它的人编写......
  • …我链接到的引导加载程序教程,OSDev wiki 显然有很多关于编写操作系统的内容。而且,与往常一样,如果您在此过程中遇到麻烦,Stack Overflow 是获得帮助的绝佳资源。但是您需要确保提出一个具体的、有针对性的问题,展示您拥有的代码并解释哪些部分不起作用。像你刚才在 cmets 中问我的那个宽泛的问题很可能会被关闭。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-08-04
  • 2013-02-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-19
  • 1970-01-01
相关资源
最近更新 更多