我厌倦了这个。我一直试图抓住装配一段时间,但我觉得我正在编写我的编译器而不是语言。
我一直在使用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上?)。有关此问题的任何具体帮助吗?
答案 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)
x86汇编程序,无论你使用什么,如GAS,NASM,A86,TASM,MASM都是一样的,有些可能有额外的语法糖,有些可能没有......
答案 4 :(得分:1)
尽管A86确实提供了一些语法糖,但立即操作数div
指令不是其中之一。 div 7
导致A86发出错误(#21,错误的单个操作数)。
我怀疑那个旧教程的作者根本没有测试他们的示例代码。
最好使用与您的工具相匹配的教程(例如,Paul Carter的NASM PC汇编语言)。您可能要查阅教科书“ 8086微处理器:PC的编程和接口”。它是专门为A86编写的,在许多在线二手书商店中售价约为5美元(2020年)。