Question

Je viens tout juste de commencer à apprendre l'assemblage x86 sur win32 et j'ai utilisé masm avec Visual Studio 2008 à l'aide de la règle de construction personnalisée fournie avec le fichier ide pour les fichiers .asm. J'ai essayé d'utiliser l'interruption DOS pour imprimer sur la console, mais je reçois le message suivant: "Exception non gérée à 0x00401004 dans ASMTest.exe: 0xC0000005: emplacement de lecture de la violation d'accès 0xffffffff." à la 8ème ligne. J'essaie de générer le caractère ascii simple 'A' (41h) Voici le code masm:

.386
.MODEL flat, stdcall

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

Lorsque j'utilise debug.exe et que j'utilise la commande 'a' pour saisir toutes les instructions .CODE et que je l'exécute ('g'), cela fonctionne correctement.

Quelqu'un peut-il m'expliquer comment utiliser correctement l'interruption DOS? Merci!

EDIT: Lors de la programmation sur win32, Managu a raison de vous demander d’utiliser un appel api Windows tel que WriteConsoleA au lieu d’utiliser l’interruption DOS. Cette était une ressource utile. Si quelqu'un cherche le code pour le faire (comme je l'étais), le voici:

.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

(Définissez le point d'entrée sur principal)

Était-ce utile?

La solution

Lorsque vous utilisez debug.exe pour saisir ce code, vous assemblez un programme dos 16 bits (architecture 8086, "mode réel"). La sémantique que vous spécifiez est correcte pour un tel programme. Cependant, lorsque vous assemblez le programme que vous avez ici avec MASM, puis que vous le liez, vous essayez de créer un programme Windows 32 bits (architecture i386, "en mode protégé"). Je peux me tromper, mais je ne pense pas que vous puissiez légalement même invoquer int 21h dans ce dernier cas.

Autres conseils

Il est possible que cela se produise à cause de votre instruction 'ret'. Où reviens-tu? Un endroit inconnu en mémoire, j'imagine.

Au lieu de cela, essayez d'utiliser int 20h. Cela se termine "gracieusement".

Cela fonctionne en mode débogage (probablement) car il s'agit d'un fichier "& géré; géré" " environnement.

Si nous lançons une application DOS - *. com 16 bits, alors DOS remplira le code opération d'un "int 20". instruction dans notre PSP à l'offset 0 et DOS supplémentaire poussant un mot avec zéro sur notre pile avant que DOS ne laisse notre application s'exécuter. Nous pouvons donc placer un simple " ret " instruction à la fin de notre code. Mais nous devons nous assurer que notre stackpointer n’est pas corrompu et que notre segment de code n’est pas modifié.

Pour lier une application 16 bits à l'aide de MASM 6+, nous avons besoin d'un éditeur de liens 16 bits.

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

Dirk

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top