IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

x86 16-bits Assembleur Discussion :

Modification interruption 08h


Sujet :

x86 16-bits Assembleur

  1. #1
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2014
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2014
    Messages : 5
    Points : 3
    Points
    3
    Par défaut Modification interruption 08h
    Bonsoir,

    Je dois revectoriser l'interruption 08h pour faire appel à une procédure perso.
    Seulement voilà, ça ne fonctionne pas ...
    • Quand je laisse l'horloge appeler mon interruption, mon débuggeur se fige à la première ligne de celle-ci et tout l'environnement (DOS & pwb) plante, sans m'informer de quoi que ce soit ...
    • A l'inverse, quand j'appelle INT 08h dans ma boucle principale, aucun soucis : le débuggeur entre dans la procédure, en ressort et tout se passe bien.

    J'ai essayé avec 1Ch, pas mieux ...

    Je précise que j'appelle une autre procédure dans ma procédure d'interruption, qui est un peu "lourde" (50 instructions à tout casser).
    J'ai cru comprendre qu'il était conseillé d'en faire le moins possible dans 08h ...
    Cela dit, même en commentant l'appel à mon autre procédure, voire tout sauf le iret, c'est pareil.

    Au cas où, l'interruption en question, bien que je doute que ça vienne de là ... Mais alors d'où ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    NewInt	proc	far
    	push	 ds
    	push	 ax
    	mov	 ax,MyData
    	mov	 ds,ax
    	assume	ds:MyData
     
    	; Ancienne 08h
    	CALL Ex08h 
           ; Ex08h est un double mot stockant l'adresse de l'ancienne 08h récupérée plus tôt de la sorte : 
            ;MOV AH, 35h
    	;MOV AL, 08h
    	;INT 21h
    	;MOV WORD PTR[Ex08h], BX
    	;MOV WORD PTR[Ex08h+2], ES
     
    	;Procédure utile au programme
    	CALL UpdateData
     
    	pop	 ax
    	pop	 ds
    	assume	ds:nothing
    	iret
    NewInt   ENDP
    Je sais que c'est très peu, mais je suis perdu et ne sais pas vraiment dans quelle direction orienter mes recherches.

    Merci d'avance pour votre aide.

  2. #2
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 400
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 400
    Points : 23 785
    Points
    23 785
    Par défaut
    Bonjour et bienvenue,

    Il y a effectivement plusieurs erreurs.

    D'abord, ton CALL est incorrect. Il manque au minimum un FAR pour lui faire comprendre qu'il faut faire un bond sur 32 bits en tenant compte du segment. Ensuite, il faut effectuer une indirection avec « [ ] » car écrit de cette façon, ton programme va sauter à l'adresse où se trouve cette variable (qui ne contient donc rien d'exécutable) et pas à l'adresse indiquée par cette variable.

    Ensuite, tu ne peux pas appeler une interruption de cette manière. Une interruption, qu'elle soit déclenchée matériellement via les IRQ ou logiciellement par l'instruction INT, provoquement l'empilement de plusieurs registres, dont les flags, et inhibe les IRQ à venir le temps de la procédure. C'est pour cela qu'il existe une instruction IRET (« Interrupt Return ») et que l'on utilise pas simplement RET. Ça veut dire que si tu souhaites appeler une autre interruption en cascade depuis ta routine, il faut soit le faire avec INT, soit empiler toi-même les bons registres pour que l'état de celle-ci soit compatible avec l'instruction IRET située au bout de l'interruption que tu appelles.

    Dans le cas le plus courant, sous DOS, quand on veut simplement faire un hook comme le tien, on redirige le vecteur sur sa routine, on effectue les tâches demandées et on termine par un JMP vers la routine originale, à qui on laisse le soin de sortir.

    Enfin, effectivement, il est recommandé d'en faire le moins possible et de s'efforcer d'écrire des routines d'interruptions les plus rapides possibles. Par exemple, si l'arrivée d'une interruption doit déclencher le démarrage d'une procédure relativement longue, il est préférable de faire en sorte que son handler lève un flag qui sera ensuite examiné par le flot normal. Il est également très déconseillé, en dépit de mon paragraphe précédent, d'appeler les interruptions en cascade. Entre autre ennuis, tu risques de faire face à des problèmes de réentrance. Il faudra alors mettre en place une sorte de mutex pour éviter les boucles infinies et les débordements de pile.

  3. #3
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2014
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2014
    Messages : 5
    Points : 3
    Points
    3
    Par défaut
    Merci pour ta réponse Obsidian.

    Si je comprends bien, si je modifiais ma procédure de la sorte :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    NewInt	proc	far
    	JMP [Ex08h]
    NewInt   ENDP
    Cela devrait fonctionner (ça ne sert à rien pour mon application, soit), ou tout du moins ça ne devrait pas planter n'est-ce pas ?

    Edit : et avec l'appel à ma procédure avant, ça fonctionne bien. Merci infiniment Obsidian ! Bon, le débuggeur continue de planter, mais l'exécution se déroule correctement.
    Puis-je abuser et poser une petite question ? Est-il normal que la mémoire ne soit pas libérée une fois le programme exécutée ? Tout du moins, PWB ne veut plus se lancer par manque de mémoire après une exécution ("programme trop grand pour tenir en mémoire")... De quoi cela pourrait-il venir ?

  4. #4
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 400
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 400
    Points : 23 785
    Points
    23 785
    Par défaut
    Citation Envoyé par Utundu Voir le message
    Cela devrait fonctionner (ça ne sert à rien pour mon application, soit), ou tout du moins ça ne devrait pas planter n'est-ce pas ?
    N'oublie pas de faire un JMP FAR !

    Puis-je abuser et poser une petite question ? Est-il normal que la mémoire ne soit pas libérée une fois le programme exécutée ? Tout du moins, PWB ne veut plus se lancer par manque de mémoire après une exécution ("programme trop grand pour tenir en mémoire")... De quoi cela pourrait-il venir ?
    Probablement de la même chose qu'au-dessus, mais c'est difficile à dire sans voir l'affaire de mes propres yeux car je ne connais pas du tout PWB.

  5. #5
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2014
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2014
    Messages : 5
    Points : 3
    Points
    3
    Par défaut
    Mon compilateur ne veut pas de cette syntaxe :
    Cela semble marcher sans ... semble ...

  6. #6
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 400
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 400
    Points : 23 785
    Points
    23 785
    Par défaut
    Citation Envoyé par Utundu Voir le message
    Mon compilateur ne veut pas de cette syntaxe :
    Étrange. Ça fonctionne avec NASM mais celui-ci est parfois plus permissif que la syntaxe originale d'Intel, ou en tout cas celle de MASM. As-tu bien remplacé « var » par « Ex08h » ?

    Cela semble marcher sans ... semble ...
    Si ton code source est appelé avant la routine initiale, tu peux en avoir l'impression effectivement

  7. #7
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2014
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2014
    Messages : 5
    Points : 3
    Points
    3
    Par défaut
    Pardon pour le retard, j'ai eu quelques soucis à régler

    Mon problème n'est pas résolu, ça ne faisait en effet que "sembler" fonctionner.
    Ma nouvelle routine, avant de passer à l'ancienne par un JMP comme abordé ci-dessus, appelle une procédure Y qui ... ne permet pas de revenir dans la routine pour la finir (un dispatcher).

    Il faudrait donc que ma routine ne passe la main à Y que lorsqu'elle s'achève. Je pense qu'il est possible de manipuler la pile pour faire ceci, de sorte que le IRET m'amène à l'endroit voulu. Mais je dois me tromper dans mes essais, car cela plante ...

    Comment pourrais-je manipuler la pile pour qu'à la sortie du JMP Ex08h, et seulement après, je passe à Y ?

    Merci

  8. #8
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 400
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 400
    Points : 23 785
    Points
    23 785
    Par défaut
    Citation Envoyé par Utundu Voir le message
    Pardon pour le retard, j'ai eu quelques soucis à régler

    Mon problème n'est pas résolu, ça ne faisait en effet que "sembler" fonctionner.
    Ma nouvelle routine, avant de passer à l'ancienne par un JMP comme abordé ci-dessus, appelle une procédure Y qui ... ne permet pas de revenir dans la routine pour la finir (un dispatcher).
    Ta routine Y a été écrite par qui ? Est-ce que c'est une autre interruption BIOS ou est-ce que c'est un sous-programme à toi ? La manière de l'appeler sera différente en fonction de ces deux cas.

    Il faudrait donc que ma routine ne passe la main à Y que lorsqu'elle s'achève. Je pense qu'il est possible de manipuler la pile pour faire ceci, de sorte que le IRET m'amène à l'endroit voulu. Mais je dois me tromper dans mes essais, car cela plante ... Comment pourrais-je manipuler la pile pour qu'à la sortie du JMP Ex08h, et seulement après, je passe à Y ?
    Il faut reconstruire ce qui est en principe empilé par l'interruption elle-même (matérielle ou via INT xx). Essaie d'empiler les flags (avec pushf) puis d'appeler la routine d'interruption habituelle avec un CALL FAR.

Discussions similaires

  1. Interruption 08h + pic8254
    Par rida_inf dans le forum x86 16-bits
    Réponses: 0
    Dernier message: 13/05/2009, 16h32
  2. Tracer une ligne droite sans les interruptions
    Par Stef784ever dans le forum x86 16-bits
    Réponses: 4
    Dernier message: 25/11/2002, 01h22
  3. [] Datagrid vide après modification des propriétés
    Par SpaceFrog dans le forum VB 6 et antérieur
    Réponses: 9
    Dernier message: 20/09/2002, 16h37
  4. Modification de l'évènement OnClick
    Par MrJéjé dans le forum C++Builder
    Réponses: 9
    Dernier message: 22/08/2002, 12h52
  5. Réponses: 11
    Dernier message: 23/07/2002, 14h33

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo