3

win32でx86アセンブリの学習を始めたばかりで、.asmファイルのideに付属するカスタムビルドルールを使用して、VisualStudio2008でmasmを使用しました。DOS割り込みを使用してコンソールに出力しようとしましたが、代わりに「ASMTest.exeの0x00401004で未処理の例外:0xC0000005:アクセス違反の読み取り場所0xffffffff」というメッセージが表示されます。8行目。単一のASCII文字「A」(41h)を出力しようとしています。masmコードは次のとおりです。

.386
.MODEL flat, stdcall

.CODE
start:
    mov dl, 41h
    mov ah, 2
    int 21h
    ret
end start

debug.exeを使用し、「a」コマンドを使用してすべての.CODE命令を入力し、それを実行すると(「g」)、正常に動作します。

DOS割り込みを正しく使用する方法を誰かに教えてもらえますか?ありがとう!

編集:win32でプログラミングする場合、Managuは、DOS割り込みを使用する代わりに、WriteConsoleAのようなWindowsAPI呼び出しを使用する必要があるというのは正しいことです。これは役立つリソースでした。誰かがこれを行うためのコードを探している場合(私がそうであったように)、ここにあります:

.386
.MODEL flat, stdcall

; Windows API prototypes
GetStdHandle proto :dword
WriteConsoleA proto :dword, :dword, :dword, :dword, :dword
ExitProcess proto :dword

STD_OUTPUT_HANDLE equ -11

.DATA
HelloWorldString db "hello, world", 10, 0

.CODE

strlen proc asciiData:dword
    ; EAX used as count, EBX as ascii char pointer, EDX (DL) as ascii char
    mov eax, -1
    mov ebx, asciiData
    mov edx, 0

    BeginLoop:
    inc eax       ; ++count (init is -1)
    mov dl, [ebx] ; *dl = *asciiptr
    inc ebx       ; ++asciiptr
    cmp dl, 0     ; if (*dl == '\0')
    jne BeginLoop ; Goto the beginning of loop

    ret
strlen endp

main proc
    invoke GetStdHandle, STD_OUTPUT_HANDLE
    mov ecx, eax
    invoke strlen, addr HelloWorldString
    invoke WriteConsoleA, ecx, addr HelloWorldString, eax, 0, 0
    ret
main endp

end

(エントリポイントをメインに設定します)

4

3 に答える 3

3

debug.exe を使用してこのコードを入力すると、16 ビット (8086 アーキテクチャ、「リアル モード」) の DOS プログラムがアセンブルされます。指定したセマンティクスは、そのようなプログラムに適しています。ただし、ここにあるプログラムを MASM でアセンブルしてからリンクすると、32 ビット (i386 アーキテクチャ、「保護モード」) Windows プログラムを作成しようとしています。私は間違っているかもしれませんが、後者の場合、合法的に int 21h を呼び出すことさえできないと思います。

于 2009-09-12T05:10:33.537 に答える
0

「ret」命令が原因で発生する可能性があります。どこに戻るの?記憶の中の未知の場所だと思います。

代わりに、int 20h を使用してみてください。それは「優雅に」終了します。

それはより「管理された」環境であるため、デバッグで(おそらく)動作します。

于 2009-09-12T04:43:48.563 に答える