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 マニュアルなど、変数の割り当てに関する情報を Web で検索しようとしましたが、必要な情報が見つからないようです。誰でも手伝ってもらえますか? これが私の(シンプルな!)コードです:

; 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 に答える