0

次のように文字列 (int DOS) を直接出力できるマクロを FASM で作成したいと考えています。

prints 'hey there!!!!'

私はそのようなコードを書きました:

format MZ

use16
stack 0x100
entry _TEXT@16:_start

;
macro prints str
{
    call @f
    db str, 0x24

    @@:
        pop dx
        mov ah, 9
        int 0x21
}

segment _DATA@16 use16
    msg db 'hi!', 0xd, 0xa, 0x24

segment _TEXT@16 use16
    _start:
        push _DATA@16
        pop ds

        prints 'hi there))) !!!!'
        prints 'me'

        mov ax, 0x4c00
        int 0x21
    ret

問題は、_DATA@16 セグメントを空 (変数なし) のままにしておくと、すべて問題ないことです。しかし、そのセグメントで新しい変数を定義すると、生の余分なシンボルが次のように表示され始めます。

それで、私を助けてもらえますか?私の間違いはどこですか?たぶん、私が望むことを達成するために間違った方法を選択したのでしょうか? 助けてください....

4

1 に答える 1

2

私が理解している限りでは、int 21h は _DATA@16 セグメントではなく _CODE@16 セグメントでオフセットを期待しているためです。したがって、最も簡単な方法は、プログラムで 1 つのセグメントのみを使用するか、.com ファイルのみを使用することです。ここにサンプルがあります:

use16
org 0x100

macro prints [str*]
{
    pusha

    if str in <0xd, 0xa, 9>\
        | str eqtype ''

        call @f
        db str, 0x24

        @@:
            pop dx
    else
        mov dx, str
    end if

    mov ah, 9
    int 0x21

    popa
}

_start:
    prints 0xd, 0xa, 9
    prints 'hi!', 0xd, 0xa
    mov ax, msg
    prints ax, 0xd, 0xa
    prints msg

    int 0x20
ret

msg db 'hey there!', 0x24

文字列、レジスタ内の文字列のアドレス、および変数を直接受け入れることができます。また、0xd (CR)、0xa (LF)、9 (TAB) の 3 つの特殊文字も処理できます。

マルチセグメント プログラムで文字列を直接表示する方法を見つけたら、回答を投稿します。

于 2013-02-20T10:31:31.550 に答える