Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
926 connectés 

  FORUM HardWare.fr
  Programmation
  ASM

  détourner l'interruption du clavier

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

détourner l'interruption du clavier

n°798960
ptitchep
Posté le 18-07-2004 à 18:49:20  profilanswer
 

Bonjour
J'ai besoin de détourner l'interruption de clavier afin de gérer les touches "manuellement" et d'une manière efficace pour mon programme. Je suis en mode protégé (avec dos4gw).
Je n'ai aucun problème pour parametrer le vecteur d'interruption:
mov ax,205h
mov bl,09
mov cx,cs
lea edx,int9
int 31h
Par contre au moment de l'execution du programme, l'interruption est bien appelée quand j'appuie sur une touche, tout ce passe normalement sauf au moment du iret qui renvoie n'importe où et provoque une erreur (retour au bureau de windows).
voici l'interruption:
 
int9 proc far              
cli
push edi
push eax
lea edi,touches
in al,60h
cmp al,128
jae relache
 
xor ah,ah
push ax
xor eax,eax
pop ax
add edi,eax
mov byte ptr [edi],1
jmp fin_int9
 
relache:
xor ah,ah
push ax
xor eax,eax
pop ax
sub ax,128
add edi,eax
mov byte ptr [edi],0
 
fin_int9:
mov al,20h
out 20h,al
pop eax
pop edi
sti
iret
int9 endp
 
Merci de votre aide
chep

mood
Publicité
Posté le 18-07-2004 à 18:49:20  profilanswer
 

n°799022
bjone
Insert booze to continue
Posté le 18-07-2004 à 20:34:24  profilanswer
 

parceque c'est iretD qu'il faut et non iret ;)

n°799023
bjone
Insert booze to continue
Posté le 18-07-2004 à 20:39:16  profilanswer
 

sinon je supposes que t'as zieuté l'archivé 7-zip que je t'avais filé ?
passque dans mon code c'était bien un iretd.

n°799910
ptitchep
Posté le 19-07-2004 à 19:50:49  profilanswer
 

j'avais pas zieuté j'aurais du mais comme ça marchait je me suis diit que j'avais autre choses a faire. Comme quoi je suis bien con, j'aurais gagné du tps! Merci bien!

n°799949
christophe​_d13
L'efficacité à tout prix.
Posté le 19-07-2004 à 21:04:05  profilanswer
 

Et la sauvegarde des flags ? Elle est où ?

n°800180
bjone
Insert booze to continue
Posté le 20-07-2004 à 03:26:34  profilanswer
 

exact :D

n°800182
bjone
Insert booze to continue
Posté le 20-07-2004 à 03:28:56  profilanswer
 

non pas exact les flags sont automatiquement pushés/popés à l'interruption et au iret.

n°800191
christophe​_d13
L'efficacité à tout prix.
Posté le 20-07-2004 à 08:09:07  profilanswer
 

Exact : Une IRET fait ceci (j'avais oublié, cela fait longtemps que je ne m'était plus penché sur les IRQ)
pushl   EFLAGS
pushl   CS
pushl   EIP
 
Par contre y a comme un bug.
Ton prog assume le fait que le segment est sélectionné (ES/DS). Erreur !
Il faut tjrs le sélectionner manuellement.
 
Avec DJGPP :
pushl     %eax
pushw     %ds
movw      ___djgpp_ds_alias, %ax
movw      %ax,%ds
 
Up> Attention, certains serveurs DPMI refuse CLI/STI
Pour ma part, avec DGJPP, mon moteur multi-tâche fonctionnait parfaitement sous Windows 98. Je viens de tester sous XP. Et ça ne se lance pas.


Message édité par christophe_d13 le 20-07-2004 à 08:16:27
n°800549
ptitchep
Posté le 20-07-2004 à 12:08:17  profilanswer
 

Merci pour tout, mais j'ai encore plusieurs questions:
1) quelle est la différence entre iret et iretd?
2) c'est quoi pushl et pushw?
Je vais voir pour DS c'est vrai que pour l'instant c'est un peu a l'arrache mais dejà ça fonctionne. Je tiens à dire que l'assembleur de DJGPP est un peu chelou pour pas grand chose:
movw %ax,%ds
à la place de
mov ds,ax
ca fait bizarre, déjà que l'assembleur est long à taper et qu'on se retrouve facilement avec des milliers de lignes...

n°800592
christophe​_d13
L'efficacité à tout prix.
Posté le 20-07-2004 à 12:54:02  profilanswer
 

1> iret et iretd
Aucune différence c'est le même op-code (0xCF). C'est simplement une dénomination pour le mode protégé où les registres sont en 32 bits. Donc IRET = IRETD. Il existe également IRETW (toujours opcodé 0xCF).
C'est juste une appelation différente pour spécifié un modèle de fonctionnement. Fait une recherche sur google.
 
2>Un peu "chelou" ? Nuance, c'est la norme at&t...
Intel = mov eax, [esi]
AT&T = movl (%esi), %eax
 
Dans la norme AT&T appliquée au x86, on spécifie toujours la taille des opérandes de manière explicite : l pour long (32 bits), w pour word (16 bits) et b pour byte (8 bits).
Ainsi "pushw" = "push word"
Cela parait lourd au début, mais cela évite les erreurs du genre :
La norme intel a un défaut :
  mov [esi], 0x12 - 8, 16 ou 32 bits ?
  mov dword ptr [esi], 0x12 - 32 bits
La norme AT&T est plus explicite :
  movl $0x12, (%esi) - 32 bits

mood
Publicité
Posté le 20-07-2004 à 12:54:02  profilanswer
 

n°800618
ptitchep
Posté le 20-07-2004 à 13:17:23  profilanswer
 

je vois, chacun son truc, moi je préfère la norme intel, c'est comme ça que j'ai commencé et je suis habitué...
 
J'ai une erreur dans mon prog qui arrive de tps en tps, jamais au meme moment et j'ai vérifié mon code, je pense que ça viens de ma nouvelle int9.
A mon avis cela vient de DS qui n'est pas "bon" pour modifier ma variable touches. J'avais déjà détourné cette int en mode réel et j'avais résolu le pb comme ça
 
dw ?
int9 proc far
push ax
push bx
push ds
xor bx,bx
mov ax,cs:[bx]
mov ds,ax
...
 
bien sur le segment de code commençait comme ça et j'avais, au moment de détourner l'interruption, mis le contenu de ds dans cs:[0]. Comme ça ds pointait tjs vers mon segment de données pendant l'int9.
J'ai tenté de faire pareil en mode protégé mais quand je modifie des octets de cs (je n'ai pas placé la variable au debut de segment cette fois) mon prog plante. Or cs est le seul point commun entre mon prog et l'int9. Comment je peux faire pour sauvegarder ds? (en norme intel, lol)

n°800628
christophe​_d13
L'efficacité à tout prix.
Posté le 20-07-2004 à 13:31:37  profilanswer
 

J'ai aussi commencé avec la norme intel et je bosse aussi bien dans l'une que l'autre.
 
Ton compilateur doit fournir le segment DS correctement. Tu dois trouver une variable qui le contient et faire si c'est possible d'un code modifiable :
_MaLigneModifiable:
mov ax, 0x2345
mov ds, ax
 
Pour modifier mov ax, 0x2345, tu fait :
mov ax, _MaLigneModifiable
add ax, 2 //C'est 2 normalement pour le modRM : reg, imm
mov bx, ds
mov cs:[ax], bx  
 
Si c'est pas 2, c'est 1 mais je suis quasiment sur que c'est 2.

n°800645
ptitchep
Posté le 20-07-2004 à 13:55:25  profilanswer
 

Le pb c'est que dès que je mais une ligne du style:
mov cs:[...],...
mon programme plante et reviens à windows...
Je sais que c'est cette ligne qui plante, je débug avec soft ice et quand j'arrive sur cette ligne je me retrouve avec un changement de segment de code, il fait quelques instructions, un ret et hop me voila sur le bureau!

n°800651
christophe​_d13
L'efficacité à tout prix.
Posté le 20-07-2004 à 14:02:34  profilanswer
 

Et oui, sous Windows, c'est logique pour lui un segment de code est read-only et execute-only.
 
Il faut trouver le moyen avec le compilateur qu'il te remplisse la variable comme je le fais avec DJGCC :
mov ax, ___djgpp_ds_alias
mov ds, ax
 
Tu dois avoir une variable globale à mettre. Faut juste que tu trouves le nom de cette dernière.

n°800659
bjone
Insert booze to continue
Posté le 20-07-2004 à 14:08:08  profilanswer
 

bin en fait l'astuce, c'est qu'en mode protégé avec Dos4gw tu ne changes jamais de DS.
 
donc potentiellement quand une interruption est issue est en mode protégé y'a beaucoup de chances que le DS soit à celui du code normal du code.
 
mais je suis d'accord il vaux mieux mettre DS au sélecteur du code normal.
 
ceci dit mon handler de clavier en mode protégé que j'utilisais avec DOS4W n'avait pas de problèmes de stabilités.
 

n°800774
ptitchep
Posté le 20-07-2004 à 15:06:56  profilanswer
 

Ben chaque fois que je break sur mon int9, ds est correct.
Mon prog tourne sans pb si je ne touche pas le clavier, et quand j'appuie sur une touche qui ne "fait rien" l'int9 remplit bien la case de mon tableau 'touches' correspondante et le prog continue normalement. Si je reste appuyé sur cette touche inutile, le prog finit par planter. C'est pour ça que je pense que ça vient de là...

n°801342
bjone
Insert booze to continue
Posté le 20-07-2004 à 23:00:32  profilanswer
 

en fait dans ton code propre, tu as peu de raisons de changer DS (et c'est toi qui le sais).
après au niveau du Dos-Extender, quand c'est son code qui s'éxécute, là c'est l'inconnue, donc c'est vrai que ce serait judicieux d'avoir une variable globale pour obtenir un DS sain.

n°801840
ptitchep
Posté le 21-07-2004 à 13:56:32  profilanswer
 

ça serait judicieux mais je ne sais pas comment faire.
je ne peux pas modifier le segment de code (j'ai essayé push cs, pop ds et de modifier avec mov ds:[edi],... mais ça plante pareil), je ne peux pas utiliser la pile puisque je ne sais pas quand l'int a lieu et je ne peux bien sur pas sauvegarder ds dans une variable puisque si ds change, je n'aurais plus accès à la variable.

n°801853
bjone
Insert booze to continue
Posté le 21-07-2004 à 14:14:03  profilanswer
 

déjà tu ne peux pas copier CS dans DS.
CS est un sélecteur sur du code.
DS est un sélecteur sur des données.

n°801856
bjone
Insert booze to continue
Posté le 21-07-2004 à 14:16:56  profilanswer
 

sinon tu utilises la technique de christophe pour modifier le code de l'interruption à l'initialisation.

n°802330
ptitchep
Posté le 21-07-2004 à 19:39:00  profilanswer
 

je viens de résoudre mon probleme mais je ne sais pas si ça va tjs fonctionner ou si c'est un coup de chance.
En debugant avec soft ice, je me suis rendu compte que pendant l'execution de mon prog, les données placées dans ds:offset étaient les même que cs:offset.
j'ai donc placé une variable sauve_ds qui contient ds:
lea edi,sauve_ds
mov ds:[edi],ds
et pendant l'int9 j'y accède avec cs:
lea edi,sauve_ds
mov ax,cs:[edi]
mov ds,ax)
la variable sauve_ds est placée au milieux de mon code (juste avant le début de l'int9 exactement) et maintenant tout fonctionne. Est-ce que c'est un grand coup de chance ou bien est-ce que cs et ds correspondent tjs comme ça?

n°802365
bjone
Insert booze to continue
Posté le 21-07-2004 à 20:31:01  profilanswer
 

oui ! je suis con.
 
avec DOS4G(W) et beaucoup d'autres Dos-Extenders (pour CwsDpmi livré avec djgpp je sais pas), le segment de code et de donnée commençent en 0.
 
donc un offset donnera la même adresse physique avec CS et DS.
 
c'est juste que contrairement au mode réel, en mode protégé tu n'as pas le droit de copier CS dans DS. (à la .com)

n°802757
christophe​_d13
L'efficacité à tout prix.
Posté le 22-07-2004 à 09:21:53  profilanswer
 

Pour DJGPP, il faut utiliser ___djgpp_ds_alias

n°803197
bjone
Insert booze to continue
Posté le 22-07-2004 à 14:51:13  profilanswer
 

mais c'est quoi une constante, ou une variable globale ? (je suis jamais tombé sur la même chose avec le watcom)

n°803685
ptitchep
Posté le 22-07-2004 à 19:34:01  profilanswer
 

moi non plus

n°803736
bjone
Insert booze to continue
Posté le 22-07-2004 à 21:02:58  profilanswer
 

chistophe ça te fait quoi un mov avec immédiat ou un mov avec offset ? (ce qui serait po logique ce qui réponds à ma question :D)

n°803739
christophe​_d13
L'efficacité à tout prix.
Posté le 22-07-2004 à 21:13:59  profilanswer
 

___djgpp_ds_alias est un immédiat remplit lors du chargement de l'application (comme pour les CALL et JMP FAR) via la table de redirection.

n°803793
bjone
Insert booze to continue
Posté le 22-07-2004 à 22:53:05  profilanswer
 

oki.
ceci expliquant cela.
 
avec Dos4Gw + Watcom, j'ai jamais vu de truc similaire, donc autant rester sur la technique de l'immédiat modifié à l'init à travers un label, ou une variable globale accédée par CS.


Message édité par bjone le 22-07-2004 à 23:00:20
mood
Publicité
Posté le   profilanswer
 


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  ASM

  détourner l'interruption du clavier

 

Sujets relatifs
[SDL]N'agit pas bien quand j'utilise le clavieractiver une touche du clavier
Hook clavierclasse Clavier
[JAVA] Pb recuperation evenement clavierObtenir ce qui est entré au clavier
[Débutant]Touches systèmes du claviergestion de clavier
[JS ] detection des touches clavier .... sans IELecture du clavier non bloquant
Plus de sujets relatifs à : détourner l'interruption du clavier


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR