1

BIOS 割り込みを使用してディスプレイにテキストを書き込む ASM コードを書き込もうとしています。このコードは、ブート セクタから実行されます。

私は持っている

msgText DB "Hello"                  ;Text
msgCol  DB 0x07,0x08,0x09,0x0A,0x0B ;Colours
msgXY   DW 0x0E26                   ;Col/Row
msgLen  DB 0x05                     ;Length

メッセージは「Hello」だけで、文字の色がそれぞれ異なります。画面上のメッセージの位置はほぼ中央で、長さは 5 です。

メッセージ/色/xy/長さを画面に書き込む関数を書きたいのですが、今のところ、これに焦点を当てましょう。

print:
  MOV AH,0x02        ;Tell BIOS we want to set the cursor position
  MOV DX,[msgXY]     ;Tell BIOS where the cursor should go
  INT 0x10           ;Call BIOS video interrupt

  XOR ECX,ECX        ;Clear ECX
  MOV CX,[msgLen]    ;Set CX = msgLen

  MOV AH,0x0E        ;We want to print characters on the screen

  _loop:
    MOV EDX,msgText  ;Move address of text to EDX
    DEC ECX          ;Temporarily decrement ECX
    ADD EDX,ECX      ;Add ECX to the address of msgText
    INC ECX          ;Increment ECX back to what it was
    MOV AL,BYTE[EDX] ;Put the contents of the memory at EDX into AL

    MOV EDX,msgCol   ;Move address of text colour to EDX
    DEC ECX          ;Temporarily decrement ECX
    ADD EDX,ECX      ;Add ECX to the address of msgCol
    INC ECX          ;Increment ECX back to what it was
    MOV BL,BYTE[EDX] ;Put the contents of the memory at EDX into BL

    INT 0x10         ;Call BIOS video interrupt
    LOOP _loop
  RET

これで、これを で呼び出すことができるはずCALL printです。

(はい、これが「Hello」を逆に出力することは知っています。それについては心配していません。「olleH」としてメモリに保存できます。気にしません。もっと大きな問題があります)

まず、設定した行が問題CX[msgLen]引き起こします。CX同等にするためにハードコードする必要が0x05ありましたが、その理由はわかりません。

第二に、おそらく同じ理由で、カラーコードを設定しようとすると、テキストの長さと同じ問題が発生します。これらの行を削除してハードコードするだけMOV BL,0x0Cで、正常に動作します。

しかし、奇妙なことに、このMOV DX,[msgXY]部分は正常に動作しているようです。

私は何時間もの間、多くのことを変更してこれを修正しようとしてきたため、正確な問題を示すことはできません. さらに、さまざまな BIOS 割り込みを呼び出すと、いくつかのレジスタが変更されるようで、非常に面倒です。また、何かをスタックにプッシュして、後でポップアウトするときも違うのでPUSHPOP完全に避けてきました。

ちなみに、この段階ではまだ x86 のリアル モードです。

確かに私がやっていることはそれほど難しいことではありません。多分私はコーヒーが必要です。それとも何かの助け?:)

4

2 に答える 2

2

さて、「まず第一に」、あなたは として定義msgLenしましdbた。するとmov cx, [msgLen]、2 バイトがロードされます。これが問題を引き起こすかどうかは、(もしあれば) の後にあるものに依存しmsgLenます。msgLenasを定義するかdw、または実行しますmov cl, [msgLen](上位ビットがクリアされているため)。

「Secondly」で同様の問題は見られません。1 バイトを 8 ビット レジスタに移動しています。このセクションで 32 ビット レジスタを使用しているのは奇妙に思えます。「はず」は機能しますが、コードが少し肥大化します。[dx]もちろん、有効な 16 ビット アドレッシング モードではありません。 bx(他の目的で使用されている)、si、またはdi. 32ビットレジスタを使用しているため、lea edx, [edx + ecx - 1]一時的にデクリメントおよびインクリメントすることなく、必要なことを行う必要がありますecx。(しかし、それがあなたの問題を解決するとは思いません)

特定の BIOS 割り込みによってレジスタが変更されることが予想されます。それがおかしいかどうかは、どの割り込みがそれを行っているかによって異なります。ほとんどの場合、そうではありません。popあなたが編集したのと同じ値にできないのpushは奇妙です。CPU のバグを発見したか、何か間違ったことをしている可能性があります。どちらがより可能性が高いと思います。:) 便利な命令なので、使えないのは残念です。ds適切なスタックを初期化しesてセットアップするブートセクタの「act I」が表示されません。おそらくそこに問題がありますか?

int 10h/13h を見たことがありますか?私はそれがあなたが望むことをすると思います(「虹」のテキスト)。テキスト アドレスが にあることを期待するという点で、これは奇妙な割り込みes:bpですが、便利です。もう 1 つの方法は、文字と色を B800h:xxxx の「スクリーン メモリ」に直接突っ込むことです (文字に 1 バイト、色に 1 バイト)。

ブートセクタを書くのは特に簡単ではありません。実際の dos (または dosbox) を利用できる場合は、(DEBUG が利用可能な) .com ファイルの一部としてルーチンを「試す」ことが役立つ場合があります。ブートセクタは dos とは異なる環境であるため、すべての問題を解決するわけではありませんが、問題を絞り込むのに役立つ場合があります。

コーヒーが役立つかもしれませんが、ほとんどの場合... 勇気!

ベスト、フランク

于 2012-11-06T09:31:24.080 に答える
0

このコードを使用できます:

mov si,msg_text
call print_colored
print_colored:
.loop:
lodsb
cmp al,0
je .done
inc bl
mov ah,0x0E
Int 0x10
jmp .loop
.done:
ret

それはあなたのストリングを色付けしますが、あなたの選択ではありません。

于 2014-06-28T11:41:20.847 に答える