いくつかのこと:
どうやら問題は
株式会社ディであります
- メモリを割り当てるときに戻り値を確認します(エラー時にキャリーが設定され、
ax
にはエラーコードが格納されます)。[COMファイルを使用している場合は、ほとんどのメモリにあなたのプログラムと割り当てのフェイル]
- 文字列命令を使用する前に方向フラグをクリア/設定する必要があります(この場合は
cld
です。 here)
ds
をコピーした後、modovideo
(暗黙的にds
を使用)にアクセスする前に復元する必要があります。
これらの変更(およびCOMファイルで機能させるためにいくつかの追加)を使用すると効果があります。私はそれをテストするためにnasm(でコンパイル)とDOSBoxを使用しました。私がDOS用にプログラミングしてからしばらく経っているので、私がメモリを割り当てる方法はおそらくバグであることに注意してください。
org 0x100
start:
; Allocate back buffer
%if 0
; Use 21h call to allocate memory (for EXE files)
mov ah, 0x48
mov bx, 64000/16
int 0x21
jc error ; carry set on error
mov [vscr_seg], ax
%else
; COM files get (most/all) available memory, grab some of it
mov bx, word [0x0002] ; Get last paragraph from PSP
sub bx, 64000/16 ; Make room for back buffer
mov [vscr_seg], bx
mov ax, ds
add ax, 0x1000 ; Program start paragraph + 64K (max of COM file)
cmp ax, bx ; Did it fit?
jae error
%endif
; Clear back buffer
mov es, [vscr_seg]
xor di, di
xor ax, ax
mov cx, 32000
cld
rep stosw
; Get previous video mode
mov ah, 0x0f
int 0x10
mov [previous_video_mode], al
; Set mode 13h (320x200 256 colors)
mov ax, 0x0013
int 0x10
; Fill half the back buffer with color 15
mov es, [vscr_seg]
xor di, di
mov ax, 0x0f0f
mov cx, 16000
cld
rep stosw
; And fill in all pixel colors at bottom row
mov di, 199 * 320
mov cx, 255
xor al, al
.fill:
; the below two instructions are equal to stosb when the direction flag is cleared
mov [es:di], al
inc di
inc al
loop .fill
; Copy from back buffer to the screen
push ds ; Remember to save DS!
mov ds, [vscr_seg]
mov ax, 0xa000
mov es, ax
xor di, di
xor si, si
mov cx, 32000
cld
rep movsw
pop ds ; ... And restore it again
; Wait for keypress
mov ah, 0x01
int 0x21
; Restore video mode
mov ah, 0x00
mov al, [previous_video_mode]
int 0x10
; Skip error block
jmp exit
error:
; Print bx and ax to facilitate debugging
push ax
call print_hex_word
pop ax
mov bx, ax
call print_hex_word
mov ah, 0x09
mov dx, error_string
int 0x21
exit:
; Exit
mov ax, 0x4c00
int 0x21
; Print 16-bit word in BX, trashes AX and DX (at least)
print_hex_word:
mov dx, bx
shr dx, 12
call print_hex_digit
mov dl, bh
call print_hex_digit
mov dl, bl
shr dl, 4
call print_hex_digit
mov dl, bl
call print_hex_digit
; New line
mov ah, 0x02
mov dl, 13
int 0x21
mov dl, 10
int 0x21
ret
print_hex_digit:
push bx
and dl, 0x0f
add dl, '0'
cmp dl, '9'
jle .print
add dl, 'A' - '0' - 10
.print:
mov ah, 0x02
int 0x21
pop bx
ret
previous_video_mode db 0
vscr_seg dw 0
error_string db 'Error occurred!', 13, 10, 7, '$'
「inc di」の問題は何ですか?あなたがそれをコメントアウトすると動作しますか?ところで、おそらくあなたの悩みを引き起こすものではありませんが、 'movsb'を使う前に' cld'で方向フラグをクリアしてください。 – user786653