我是在写汇编还是NASM?

4

我已经受够了。我一直在尝试掌握汇编语言,但感觉自己只是在为编译器而不是为语言编码。

我一直在使用这个教程,但到目前为止,它给了我很大的困扰。我正在使用NASM,可能是问题所在,但我想这是最流行的汇编器。我只是想学习最通用的汇编语言形式,所以我决定学习x86。然而,我不断遇到愚蠢的错误,例如无法递增变量。这是最新的一个例子:无法使用div指令。

mov bx, 0;
mov cx, 0;
jmp start;
 start:
 inc cx;
 mov ax, cx;
 div 3; <-- invalid combination of opcode and operand
 cmp ah,0;
 jz totalvalue;
 mov ax, cx;
 div 5; <-- invalid combination of opcode and operand
 cmp ah, 0;
 jz totalvalue;
 cmp cx, 1000;
 jz end;

 totalvalue:
 add bx,cx;
 jmp start;

jmp end;
 end:
   mov ah,4ch;
   mov al,00;
   int 21h;

我应该更换编译器吗?似乎除法应该是标准的。我需要阅读两个教程(一个关于NASM,一个关于x86)吗?对于这个问题有什么具体的帮助?


NASM是x86机器码的汇编语言之一。所有x86汇编语言的共同点是,一行汇编源代码将汇编为单个x86机器指令。它们的区别在于指令(非指令行)和寻址模式所使用的语法等方面。其他ISA(如ARM)具有不同的指令和寄存器名称,甚至某些事物的语法也不同。 - Peter Cordes
5个回答

10
这样想:x86架构只能理解机器码。像NASM这样的汇编器将从汇编语言翻译成机器码。因此,只要选择正确的汇编器进行正确的翻译(NASM可以),你选择哪个汇编器并不重要。
这类似于使用javac或Eclipse内置编译器的问题。它们都可以编译有效的Java代码。我知道汇编器还支持一些额外的宏等东西,但在这种情况下似乎并不适用。
此外,NASM网站本身只指向x86汇编的英特尔文档,因此您可以确定它不需要某种特殊形式的文档。
现在,我发现了这个网站,记录了DIV指令,并且有以下内容:

The 80x86 divide instructions perform a 64/32 division (80386 and later only), a 32/16 division or a 16/8 division. These instructions take the form:

            div     reg     For unsigned division
            div     mem

            idiv    reg     For signed division
            idiv    mem

            aad             ASCII adjust for division
那就可以解释你的错误了。 div 的参数可以是寄存器或内存地址,但你给了一个常量。

3
我想补充一下,div操作码不接受立即数(这是它们的称呼,而不是“常量”)。如果你查看操作码参考资料,立即操作数会用缩写"imm"表示,有时会跟上大小,例如32位的"imm32"和16位的"imm16"等。有几个操作码有类似于这样奇怪的要求,但div是最让人烦恼的一个。如果你需要更详细的信息,请参考http://ref.x86asm.net/coder32.html,其中包括了所有指令和可能的操作符组合。 - Sparafusile

7

英特尔不支持立即数作为除数(只支持寄存器和内存),因此无论你使用的是什么教程,它都是针对非标准汇编语言编写的。


5
汇编语言和其他语言一样,部分定义由汇编器决定。对我来说,“div 5”听起来很奇怪 - 但我是使用具有不同语法的MASM学习汇编语言的。根据教程中的评论,看起来该教程使用的汇编器对指令有一些“隐含”的操作数,而NASM则没有,并且期望使用Intel语法进行div指令。
在我看来,最好使用NASM,并获得一个针对纯Intel语法或特定于NASM的教程。Art of Assembly书籍是Intel语法的良好资源。
(编辑:如果上面的链接失败,请尝试this,这是上面的链接转发到的位置)

《汇编语言艺术》第二版也可以在O'Reilly/Safari图书上找到。 - JimLohse

2
虽然A86提供了一些语法糖,但是立即操作数div指令不是其中之一。 div 7会导致A86发出错误(#21,单个操作数错误)。
我怀疑那个旧教程的作者只是没有测试他们的示例代码。
最好使用与您的工具匹配的教程(例如,Paul Carter的NASM PC汇编语言)。 您可能想查看教材《8086微处理器:编程和PC接口》。它专门为A86编写,可以在许多在线二手书店以约5美元(2020年)的价格获得。

1

嗯,你正在使用不同的汇编编译器方言...手册明确说明,它是共享软件汇编器包A86(哇,那是很久以前的事了!)你最好查看一些nasm教程,顺便说一句,这里有一个关于最佳nasm教程的问题here

x86汇编器无论你使用的是GAS、NASM、A86、TASM还是MASM,都基本相同,有些可能有额外的语法糖,而其他则可能没有...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接