Frage

Ich habe gerade damit begonnen, auf win32 einig x86-Assembler zu lernen, und ich habe masm mit Visual Studio 2008 mit der benutzerdefinierten Buildregel verwendet, die für .asm Dateien mit dem ide kommt. Ich habe versucht, das DOS zu verwenden, unterbrechen, um die Konsole zu drucken, sondern erhalte ich die Meldung: „Nicht behandelte Ausnahme bei 0x00401004 in ASMTest.exe: 0xC0000005: Zugriffsverletzung Leseort 0xffffffff.“ auf der 8. Zeile. Ich versuche, das einzelne ASCII-Zeichen 'A' (41h) Hier ist der masm Code zur Ausgabe:

.386
.MODEL flat, stdcall

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

Wenn ich debug.exe, und verwenden Sie den ‚a‘ Befehl zur Eingabe aller .CODE Anweisungen, und führen Sie es ( ‚g‘), es funktioniert gut.

Kann jemand mich aufklären, wie richtig die DOS-Interrupt zu bedienen? Dank!

EDIT: Wenn auf dem Win32-Programmierung, Managu richtig ist, dass Sie einen Windows-API-Aufruf wie WriteConsoleA stattdessen das DOS-Interrupt der Verwendung verwendet werden sollen. Diese eine hilfreiche Ressource war. Sollte diese (wie ich war) jemand für den Code ist auf der Suche zu tun, hier ist es:

.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

(Stellen Sie den Einstiegspunkt zur Haupt)

War es hilfreich?

Lösung

Wenn Sie debug.exe zur Eingabe von diesen Code verwenden, sind Zusammenbauen Sie eine 16-Bit (8086 Architektur, "real mode") DOS-Programm. Die Semantik Sie sind für ein solches Programm korrekt angeben. Wenn Sie jedoch das Programm zusammenstellen, Sie haben hier mit MASM bekommen, und dann verknüpfen, sind Sie eine 32-Bit zu erstellen versuchen, Windows-Programm (i386-Architektur „-Modus geschützt“). Ich konnte irren, aber ich glaube nicht, können Sie rechtlich auch int 21h im letzteren Fall aufrufen.

Andere Tipps

Es ist möglich, dass es wegen Ihrer ‚ret‘ Anweisung auftritt. Wo kehren Sie zu? Ein unbekannter Ort in Erinnerung, ich stelle mir vor.

Stattdessen versuchen int 20h verwenden. Das wird "anmutig." Beenden

Es funktioniert im Debug (wahrscheinlich), denn das ist eine "managed" -Umgebung.

Wenn wir eine 16-Bit-DOS starten - *. Com Anwendung, dann füllt DOS den Opcode einer „int 20“ Anweisung innerhalb unseres PSP bei 0 versetzt und zusätzliches DOS ein Wort mit Null auf unserem Stapel schieben, bevor DOS ließ unsere Anwendung auszuführen. So können wir eine einfache „ret“ Anweisung am Ende unseres Codes platzieren. Aber wir müssen sicherstellen, dass unsere Stackpointer nicht beschädigt sind und unser Codesegment wird nicht verändert.

Für eine 16-Bit-Anwendung zu verknüpfen MASM mit 6+ wir ein 16-Bit-Linker benötigen.

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

Dirk

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top