我在写装配还是NASM?

时间:2010-05-20 14:32:21

标签: assembly nasm

我厌倦了这个。我一直试图抓住装配一段时间,但我觉得我正在编写我的编译器而不是语言。

我一直在使用this tutorial,到目前为止它给了我地狱。我正在使用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上?)。有关此问题的任何具体帮助吗?

5 个答案:

答案 0 :(得分:8)

以这种方式思考:x86架构实际上只能理解机器代码。像NASM这样的汇编程序将从汇编代码转换为机器代码。所以你选择汇编程序并不重要,只要它做正确的翻译(NASM就是这样)。

这类似于是否使用javac或Eclipse的内置编译器的问题。他们都将编译有效的Java。我知道汇编程序也支持一些额外的宏和类似的东西,但这似乎不适用于这种情况。

此外,NASM site本身只是指向x86汇编的英特尔文档,因此您可以确定它不会期望它的某些特殊形式。

现在,我确实找到了记录DIV指令的site,并且有这样的说法:

  

执行80x86除法指令   64/32师(80386及以后)   只有),32/16分区或16/8分区   师。这些说明采取了   形式:

            div     reg     For unsigned division
            div     mem

            idiv    reg     For signed division
            idiv    mem

            aad             ASCII adjust for division

这样可以解释你的错误。 div的参数可以是寄存器或内存位置,但是你给它一个常量。

答案 1 :(得分:6)

与其他任何语言一样,汇编的一个原因是它部分由汇编程序定义。那个“div 5”对我来说似乎很奇怪 - 但是我学会了使用MASM的汇编,它有不同的语法。基于本教程中的注释,看起来用于该教程的汇编程序对指令有一些“隐含的”操作数,而NASM则没有,并且期望div指令的Intel语法。

恕我直言,你最好通过使用NASM,但获得一个NASM特定的教程,或者面向'纯'英特尔语法的教程。 Art of Assembly本书是英特尔语法的一个很好的资源。

答案 2 :(得分:5)

英特尔不支持立即参数div(仅限寄存器和内存参数),因此您使用的任何教程都是为非标准汇编程序构建的。

答案 3 :(得分:2)

嗯,你正在使用汇编程序编译器的另一种方言......手册清楚明确地说明了它的A86汇编程序是一个共享软件汇编程序包(很久以前的gee !!!)你最好的选择是请查看一些nasm教程,顺便提一下here关于最好的nasm教程的问题。

x86汇编程序,无论你使用什么,如GAS,NASM,A86,TASM,MASM都是一样的,有些可能有额外的语法糖,有些可能没有......

答案 4 :(得分:1)

尽管A86确实提供了一些语法糖,但立即操作数div指令不是其中之一。 div 7导致A86发出错误(#21,错误的单个操作数)。

我怀疑那个旧教程的作者根本没有测试他们的示例代码。

最好使用与您的工具相匹配的教程(例如,Paul Carter的NASM PC汇编语言)。您可能要查阅教科书“ 8086微处理器:PC的编程和接口”。它是专门为A86编写的,在许多在线二手书商店中售价约为5美元(2020年)。