我决定学习汇编程序以获得乐趣。我用C编写了很多年。
我按照一些在线教程打印了“Hello world”并在NASM手册中挖了一下。一切都很好。所以,我为自己设定了一个循环打印“hello world”的任务。我知道我可以使用loop
操作码执行此操作,但希望显式编码并使用.bss
部分中定义的变量。
但是,当我收到错误消息时,我显然误解了变量赋值在程序集中的工作原理:
nasm -felf -o hello.o hello.asm
hello.asm:16: error: invalid combination of opcode and operands
hello.asm:17: error: invalid combination of opcode and operands
hello.asm:28: error: invalid combination of opcode and operands
我尝试在网上搜索有关变量分配的信息,包括NASM手册,但似乎无法找到我需要的信息。有人可以帮忙吗?这是我的(简单!)代码:
; print "Hello world!" to the screen multiple times
section .data
msg: db 'Hello world!', 10
msglen: equ $ - msg
section .bss
iter: resb 1
section .text
global _start
_start:
; loop 10 times
mov iter, 0 ; initalise loop counter
FL: cmp iter, 10 ; is iter == 10?
jge LoopEnd
; write the message to STDOUT:
mov eax,4 ; code for write syscall
mov ebx,1 ; stdout fd
mov ecx,msg ; message to print...
mov edx,msglen ; ...and it's length
int 80h ; kernel interrupt
; increment loop iterator
inc iter
jp FL
LoopEnd:
; now exit, with return code 0:
mov eax,1
mov ebx,0
int 80h
答案 0 :(得分:5)
要在nasm中创建内存引用,必须用方括号括起地址。此外,在您到达的每个案例中,您还需要指定大小,如下所示:
mov byte [iter], 0 ; initalise loop counter
FL: cmp byte [iter], 10 ; is iter == 10?
inc byte [iter]
但是,在这种情况下,将iter
存储在寄存器而不是内存中可能更有意义。您通过系统调用破坏了大部分显而易见的问题,但esi
或edi
看起来可用。
答案 1 :(得分:2)
我认为必须放在括号内。试试[iter]
。
如果您有这样的问题,请参阅NASM docs。
在这种情况下,Effective Addresses上的部分:
有效地址是引用存储器的指令的任何操作数。在NASM中,有效地址具有非常简单的语法:它们由一个表达式组成,该表达式用方括号括起来评估所需的地址。例如:
wordvar dw 123
mov ax,[wordvar]
mov ax,[wordvar+1]
mov ax,[es:wordvar+bx]