0

組み立てを理解しようとしています。今日のトピックは次のとおりです:「int 変数の格納とインクリメントおよび数値の出力」:)

だからここに私のコードがあります

dane segment
     count     db     0
dane ends

code segment
start:
     inc     byte ptr ds:[count]
     inc     byte ptr ds:[count]
     inc     byte ptr ds:[count]

     mov     dl,ds:[count]
     mov     ah,2
     int     21h

     mov     ah,4ch
     int        21h
code ends
end start

コンパイルして実行すると、次のエラーが発生しました。

ここに画像の説明を入力

countが複数回インクリメントされた場合にのみ発生します。私は何を間違っていますか?

単純に書けない理由を誰か説明できますか:

inc     count

また、値をインクリメントするときに入れbyte ptrなければならないのに、それをコピーしてdl登録するのはなぜですか?

4

2 に答える 2

3

編集:テキストを書き直して追加し、コードを追加しました(MASM 6.11で動作します):

x86 アセンブリでは、あいまいさがある命令のメモリ オペランドのサイズを指定する必要があります。などでオペランドのサイズをアセンブラに伝える必要があります。そのためbyte ptr、. 別の命令です。word ptrinc byte ptr ds:[count]byte ptrinc word ptr ds:[count

mov dl,ds:[count]は8 ビット レジスタであり、メモリ オペランドのサイズは常に同じバイト (8 ビット) であるbyte ptrため、必要ありません。dl

文字を印刷するには、最初に数値を文字列 (または 10 未満の数値の場合は 1 文字) に変換する必要があります。それ以外の場合は、ASCII コード 3 を持つ制御文字 ETX ( ASCII 表30hを参照) を出力しています。

mov dl,ds:[カウント]
dl、「0」を追加します。dl,30h を追加

x86 アセンブリで 10 進数で印刷することはよく聞かれます。たとえば、「このコードは正しいですか (数値と数値を加えて、結果を印刷する) 」を参照してください。

編集: EXE ファイルにはスタック セグメントも必要です。

DOS EXE ファイルには、スタック セグメントが必要です。dosexe.asmMASM 6.11 でアセンブルしても、基本的に(dosexe.asm をアセンブリ コード ファイル名に置き換えてください) 、警告やエラーは発生しません。

ただし、ML ( ml dosexe.obj) でリンクすると、次の警告が表示されます。

リンク: 警告 L4021: スタック セグメントがありません

そのため、スタック セグメントを追加する必要があります。次の行をソースの先頭に追加します。

.モデル小
.スタック 4096

データセグメントの定義にも問題がありましたが、それも修正しました。

修正されたアセンブリ コード全体は次のようになります (MASM 6.11 で動作します)。

.モデル小
.スタック 4096

。データ
        カウント デシベル 0

。コード
始める:
        移動軸、セグメント数
        mov ds,ax

        inc バイト ptr ds:[カウント]
        inc バイト ptr ds:[カウント]
        inc バイト ptr ds:[カウント]

; このコードは、逆にする必要なく10進数で印刷します
; 除数を除算することにより、文字列。100/10 = 10

        mov bl,100 ; 元の除数。

        mov al,ds:[カウント]

印刷ループ:
        xorああ、ああ; 被除数の上位 8 ビットをクリアします (ax で)。
        div bl ; ax を bl で割ります。al の商、ah の余り。

        mov dl、al ; ah = 2, int 21h で出力される値

        ムーアル、ああ; 残りは次のループで除算されます。
        テスト dl、dl ; 数値がゼロかどうかを調べる
        jz not_print ; 先行ゼロを出力しません。

        dl、「0」を追加します。ASCII 数字範囲に変換します。
                          ; 「0」= 0x30 = 48
        押し斧
        動くああ、2
        int 21h ; Ralf Brown's に従って、値を出力します
        ポップアックス; 割り込みリストは al を返します。

not_print:
        押し斧
        移動する
        ああ、ああ
        移動 bl,10 ; 除数を 10 で割ります。
        部門黒
        移動 bl,al ; 新しい除数。
        ポップアックス
        テストbl、bl
        jnz print_loop

        動くあ、4ch
        整数 21h
終了開始
于 2013-03-23T09:58:35.250 に答える
0

[quote]mov dl,ds:[count] dl は 8 ビット レジスタであり、メモリ オペランドのサイズは常に同じバイト (8 ビット) であるため、バイト ptr は必要ありません。[/quote]

さらに、DS はこの操作のデフォルト セグメントであるため、この操作にはセグメント オーバーライド プレフィックスは必要ありません。=> mov dl,[count]

編集:

セグメント属性を持つ name という名前のプログラム セグメントを定義します。

http://msdn.microsoft.com/de-de/library/d06y3478%28v=vs.80%29.aspx

name SEGMENT [[READONLY]] [[align]] [[combine]] [[use]] [[characteristics]] ALIAS(string) [['class']]
  statements
  name ENDS

セグメント名の使用例:

CODE SEGMENT use16 'CODE'
assume cs:CODE,ds:DATEN,ss:STAPEL
org 100h
START:
mov ax, DATEN
mov ds, ax

; your instructions

CODE ends

DATEN SEGMENT use32 'DATA'
org 0
VALUE  DD ?
DATEN ends

STAPEL SEGMENT use16 STACK 'STACK'
   DB 10h dup (0)
STAPEL ends

end

セグメントとディレクティブの使用方法:

http://cs.smith.edu/~thiebaut/ArtOfAssembly/CH08/CH08-3.html

...

MASM 6 を使用して 16 ビット アプリケーションをリンクするには、別のリンカーが必要です。

ftp://ftp.microsoft.com/softlib/mslfiles/lnk563.exe

ダーク

于 2013-03-28T06:34:35.900 に答える