1

単純な TSR プログラムを作成していますが、エラーが発生します。

で実行しようとしましたInt 90Hが、何らかの理由でクラッシュしました。

私はTSRを初めて使用するので、問題は単純かもしれません。

TSR:

;   Copy non-small letters

.model tiny
.code
    ORG 100H
start:
    push bp
    push si
    push cx
    push bx
;   save registers
    mov bp, sp
    sub sp, cx
    sub sp, 1 ; for $
    mov di, bp
    mov si, bx
copy:
    cmp [si], 'a'
    jl  bad
;   not small letter
    cmp [si], 'z'
    jg  bad
;   not small leter
;   good
    mov ax, [si]
    mov [bp], ax
    dec bp
bad:
    inc si
loop copy
    mov [bp-1],'$'
    mov ah, 09
    mov dx, di
    int 21H
install:
    mov al, 90H
    mov ah, 25H
    mov dx, offset start
    int 21H
finish: 
    pop bx
    pop cx
    pop si
    pop bp
;   ^ restore registers
    mov ah, 31
    int 21H
    iret
;   end
end start

メインプログラム:

.model small
.stack 64
.data
    string  db  "Hey There"
.code
start:
    lea bx, string
    mov cx, 09
    int 90H
;   end
    mov ah, 4ch
    int 21H
end start

私のプログラムがクラッシュする理由を知っていますか?

4

2 に答える 2

0

私は 10 年以上前に DOS 用の TSR デバッガー (一種の) を作成したので、何かを忘れている可能性があります。

csとにかく、割り込みハンドラーは、割り込みハンドラーのセグメントを指し、ip(明らかに) 割り込みコードを指していること以外は何も想定してはなりません。特に変更したい)。使用するすべてのレジスタを格納する必要がありますがpush、スタックが残っていると想定できないため、それらだけをスタックに格納することはできません。そのため、割り込みハンドラで変更するすべてのレジスタを保存するのに十分なメモリを確保してください。また、レジスタを保存するときは、デフォルトの 、、、またはではなくcs、セグメント レジスタとして使用することを忘れないでください。dsesfsgsss、それらはすべてメモリ内の任意の場所を指している可能性があり、TSR に予約されているメモリのチャンクを指しているわけではないためです。旗の収納もいいですね。

int 21h通常、割り込みハンドラでは呼び出しを避ける必要があります。BIOS 呼び出し ( int 10h) またはビデオ メモリへの直接書き込みを使用できます (ただし、TSR でビデオ メモリに書き込む場合は、最初にビデオ モードを確認してください)。とにかく、現在実行中のプログラムがそれをどのように使用するかがわからないため、TSR のビデオ メモリに書き込むと問題が発生する可能性があります。

独自の割り込みハンドラー中に他の割り込みが実行されないようにしたい場合はcli、割り込みハンドラーの最初でほとんどの割り込みをブロックし、IMHO を使用することをお勧めします。sti直前まで割り込みを許可することを忘れないでくださいiret

于 2012-08-25T13:24:48.597 に答える