3

我决定为了好玩而学习汇编程序。我已经用 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
4

2 回答 2

7

要在 nasm 中进行内存引用,您必须用方括号将地址括起来。此外,在您在这里遇到的每种情况下,您还需要指定大小,如下所示:

    mov byte [iter], 0     ; initalise loop counter
FL: cmp byte [iter], 10    ; is iter == 10?

    inc byte [iter]

iter但是,在这种情况下,存储在寄存器中而不是存储在内存中可能更有意义。您正在使用系统调用破坏大多数明显的调用,但esi或者edi看起来可用。

于 2012-10-17T21:24:24.483 回答
4

我认为它必须在括号中。试试[iter]

每当您有此类问题时,请参阅NASM 文档。

在这种情况下,有效地址部分:

有效地址是引用内存的指令的任何操作数。在 NASM 中,有效地址有一个非常简单的语法:它们由一个计算为所需地址的表达式组成,用方括号括起来。例如:

wordvar dw 123
mov ax,[wordvar]
mov ax,[wordvar+1]
mov ax,[es:wordvar+bx]
于 2012-10-17T21:21:51.303 回答