我决定学习汇编器以娱乐。我已经在C中编码了很多年。
我遵循了一些在线教程,这些教程打印了" Hello World",并在NASM手册中挖了一点。一切都很好。因此,我为自己设定了在循环中打印" Hello World"的任务。我知道我可以使用loop
opcode执行此操作,但想明确编码并使用.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
要在nasm中进行内存参考,您必须用方括号包围地址。此外,在您这里遇到的每种情况下,您还需要指定大小,例如:
mov byte [iter], 0 ; initalise loop counter
FL: cmp byte [iter], 10 ; is iter == 10?
inc byte [iter]
在这种情况下,将iter
存储在寄存器中而不是在内存中可能更有意义。您正在使用系统调用中大多数显而易见的声音,但是esi
或edi
看起来很可用。
我认为它必须在括号中。尝试[iter]
。
每当您有这样的问题时,请参阅NASM文档。
在这种情况下,有关有效地址的部分:
有效的地址是参考内存的指令的任何操作数。有效的地址在NASM中具有非常简单的语法:它们由评估所需地址的表达式组成,该地址包含在方括号中。例如:
wordvar dw 123
mov ax,[wordvar]
mov ax,[wordvar+1]
mov ax,[es:wordvar+bx]