Modifer le vecteur d'interruptions

Résolu
vecchio56 Messages postés 6535 Date d'inscription lundi 16 décembre 2002 Statut Membre Dernière intervention 22 août 2010 - 31 août 2005 à 15:10
 cs_Nasman - 5 sept. 2005 à 09:39
Bonjour
J'essaie de refaire la source http://www.cppfrance.com/code.aspx?ID=33558 en assembleur (ca consiste à modifier la routine de l'interruption 08h). Le problème est que programme se termine aussitôt après avoir été lancé.
Voici mon code:

.model small
.stack

.data
oldTimerSegment DW ?
oldTimerOffset DW ?

.code

; place la valeur de ds dans le code pour pouvoir le récupérer
; dans myTimer
DataSegment DW ?

myTimer:
push ax bx dx

mov ah, 2
mov dl, '.'
int 21h

mov ax, DataSegment
mov es, ax
mov ax, es:oldTimerSegment
mov bx, es:oldTimerOffset

mov es, ax
call es:[bx]
pop dx bx ax
iret

main:
mov ax, @data
mov ds, ax
mov DataSegment, ax

; Modification du vecteur d'interruptions
xor ax, ax
mov es, ax
mov bx, 20h ; 8*4=20h

; premier mot: offset de la procédure
mov ax, es:[bx]
mov oldTimerOffset, ax
mov ax, offset myTimer
mov es:[bx], ax

; deuxième mot: valeur de segment de code
mov dx, es:[bx+2]
mov oldTimerSegment, dx
mov ax, cs
mov es:[bx+2], ax

; attend l'appui d'un touche
mov ah, 1
int 21h

mov ah, 4Ch
int 21h

end main

37 réponses

cs_patatalo Messages postés 1466 Date d'inscription vendredi 2 janvier 2004 Statut Modérateur Dernière intervention 14 février 2014 2
3 sept. 2005 à 14:02
[BITS 16]
[ORG 0x100]


main: ; cs ds es = ss
mov word [compteur],0
mov ax,3508h
int 21h
mov dx,es
mov [pfOldTimer], bx
mov [pfOldTimer+2], dx
lea dx,[myTimer]
mov ax,2508h
int 21h
.1
mov ah, 1
int 21h
cmp al,'q'
je .1
cmp al,'Q'
jne .1
mov ah, 4Ch
int 21h


pfOldTimer:
dw 0
dw myTimer
compteur:
dw 0


myTimer:
pusha
push ds
push es
mov ax,cs
mov ds,ax
mov es,ax
inc word [compteur]
cmp word [compteur],18
jne .1
mov word [compteur],0
mov ah,2
mov dl,'.'
int 21h
.1
pushf
push cs
push .ip_
jmp far [pfOldTimer]
.ip_
pop es
pop ds
popa
iret


; nasmw -f bin hookint.asm -o hookint.com
; bizarrement, windows XP signale parfois une erreur ?
; j'ai été obligé de mettre la touche 'Q' en particulier car a l'appel de la fonction 2
; provoquait l'arret du programme.
; d'ailleur la fonction 2 devait modifier un registre non sauvegardé ( d'ou pusha )
; j'ai modifier le changement de vecteur par des appels DOS mais le tien doit
; etre bon
;@++
3
vecchio56 Messages postés 6535 Date d'inscription lundi 16 décembre 2002 Statut Membre Dernière intervention 22 août 2010 14
31 août 2005 à 19:08
J'ai modifié plusieurs choses mais j'y arrive toujours pas. Mon programme se comporte différemment: des fois il plante, des fois il affiche des pointes puis il s'arrête, des fois il se termine tout de suite...

.model small
.stack

.data
oldTimerSegment DW ?
oldTimerOffset DW ?

.code

; place la valeur de ds dans le code pour pouvoir le récupérer
; dans myTimer
DataSegment DW ?
compteur DW 0

myTimer:
push ax ds es

; simule un int: empile flags, cs et ip
pushf
push cs
push offset ip_

mov ds, DataSegment
inc compteur
cmp compteur, 18
jne noReset
mov compteur, 0
mov ah, 2
mov dl, '.'
int 21h
noReset:

mov ax, oldTimerSegment
mov es, ax

ip_:
jmp es:oldTimerOffset ; appel de la routine par défaut

pop es ds ax
iret


main:
mov ax, @data
mov ds, ax
mov DataSegment, ax

; Modification du vecteur d'interruptions
xor ax, ax
mov es, ax
mov bx, 20h ; 8*4=20h


mov ax, es:[bx]
mov oldTimerOffset, ax
mov dx, es:[bx+2]
mov oldTimerSegment, dx


mov ax, offset myTimer
mov dx, cs
cli
mov es:[bx], ax
mov es:[bx+2], dx
sti

mov ah, 1
int 21h

mov ah, 4Ch
int 21h

end main
0
cs_patatalo Messages postés 1466 Date d'inscription vendredi 2 janvier 2004 Statut Modérateur Dernière intervention 14 février 2014 2
1 sept. 2005 à 10:42
salut,

il faut que ton programme reste resident

@++
0
vecchio56 Messages postés 6535 Date d'inscription lundi 16 décembre 2002 Statut Membre Dernière intervention 22 août 2010 14
1 sept. 2005 à 11:17
Ah? ca veut dire quoi?
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cs_patatalo Messages postés 1466 Date d'inscription vendredi 2 janvier 2004 Statut Modérateur Dernière intervention 14 février 2014 2
1 sept. 2005 à 11:36
re,


quand tu finis un programme avec la fonction 4C de l'int 21h, cela veut dire que ton programme doit etre déchargé de la memoire. La memoire ainsi libérée est utilisée pour un autre programme.


tu dois rendre ton programme résident ( il doit rester en mémoire ) je crois que c'est l'int 27h qui fait ça ( dx prends le nombres de paragraphes ).

lors du déchargement de ton programme, n'oublie pas de remettre le vecteur d'interruption vers la bonne addresse.


@++
0
vecchio56 Messages postés 6535 Date d'inscription lundi 16 décembre 2002 Statut Membre Dernière intervention 22 août 2010 14
1 sept. 2005 à 11:42
mov ah, 1
int 21h

Ca attend l'appui d'une touche sur le clavier, donc normalement mon programme va rester résident. Il y a donc un problème ailleurs

A quoi ca sert de remettre la bonne adresse à la fin, puisque mon programme se termine?
0
cs_patatalo Messages postés 1466 Date d'inscription vendredi 2 janvier 2004 Statut Modérateur Dernière intervention 14 février 2014 2
1 sept. 2005 à 12:08
re,

je serais toi, je mettrais plutot une boucle infinie pour test.

qui prouve que le le programme ne chope pas un caractere qui traine dans STDIN dès l'execution ? ( fait un flush du buffer avant la demande )

@++
0
vecchio56 Messages postés 6535 Date d'inscription lundi 16 décembre 2002 Statut Membre Dernière intervention 22 août 2010 14
1 sept. 2005 à 12:12
Une boucle infinie ca prend un peu trop de cpu a mon gout. Quand je change pas l'interruption, le programme attend toujours l'appui... Tu sais comment on fait un flush en asm?
Au fait je suis sous XP, donc en mode virtuel et pas en mode réel, donc la table d'interruption n'appartient qu'a mon programme, non?
0
cs_patatalo Messages postés 1466 Date d'inscription vendredi 2 janvier 2004 Statut Modérateur Dernière intervention 14 février 2014 2
1 sept. 2005 à 12:39
c'est pas le genre de truc que je ferais tourner sous XP.
le code myTimer me parait aussi louche ( simule int ? )
voilà un exemple de TSR ( le 16 bits, ça fait longtemps que j'en fais plus que pour les secteurs de boot )
http://www.geocities.com/SiliconValley/2072/asm.htm
0
vecchio56 Messages postés 6535 Date d'inscription lundi 16 décembre 2002 Statut Membre Dernière intervention 22 août 2010 14
1 sept. 2005 à 12:51
J'appelle une routine d'interruption, mais comme elle va dépiler cs, il faut que je l'empile avant
Merci pour le lien et pour ton aide
0
cs_patatalo Messages postés 1466 Date d'inscription vendredi 2 janvier 2004 Statut Modérateur Dernière intervention 14 février 2014 2
1 sept. 2005 à 13:01
j'ai regardé le source cpp et c'est a mon avis une mauvaise idée.
pour avoir l'heure/minute/seconde, il faut lire les registres CMOS et pas compter 18 appels pour 1 seconde car la valeur exacte et 18,2 ce qui donne une horloge fausse.

@++
0
vecchio56 Messages postés 6535 Date d'inscription lundi 16 décembre 2002 Statut Membre Dernière intervention 22 août 2010 14
1 sept. 2005 à 13:21
Oui je sais, c'est juste pour le principe de modifier une routine d'interruption
0
cs_patatalo Messages postés 1466 Date d'inscription vendredi 2 janvier 2004 Statut Modérateur Dernière intervention 14 février 2014 2
2 sept. 2005 à 10:17
j'ai vu un autre truc:
Attention car tu declare DataSegment dans le code.


mov ds,DataSegment -> mov ds,cs:[DataSegment]

@++
0
cs_patatalo Messages postés 1466 Date d'inscription vendredi 2 janvier 2004 Statut Modérateur Dernière intervention 14 février 2014 2
2 sept. 2005 à 10:22
encore un truc.

ton label "ip_" doit etre placé apres le jmp sinon tu boucle en infini sauf qu'au 2eme appel la pile est fausse.

@++
0
vecchio56 Messages postés 6535 Date d'inscription lundi 16 décembre 2002 Statut Membre Dernière intervention 22 août 2010 14
2 sept. 2005 à 10:51
Visiblement ca ne change rien de mettre cs: devant DataSegment (il me sort le même executable)
Pour _ip je savais pas si on mettait avant ou après, de toutes facons ca foire dans les 2 cas
Merci quand même
0
cs_patatalo Messages postés 1466 Date d'inscription vendredi 2 janvier 2004 Statut Modérateur Dernière intervention 14 février 2014 2
2 sept. 2005 à 11:25
ça foirera tant que tu n'auras pas réglé tout les bugs.


peut etre que l'assembleur a déjà spécifié cs vu que dans .code
le _ip doit etre derriere.
au fait, le .stack, faut pas lui reserver un peu de place ?
.stack
dw 100h dup(?)

@++
0
vecchio56 Messages postés 6535 Date d'inscription lundi 16 décembre 2002 Statut Membre Dernière intervention 22 août 2010 14
2 sept. 2005 à 11:51
Je veux bien régler mes bugs, seulement j'arrive pas à les trouver! Si tu en vois tu peux me dire :)
Pour la pile j'ai jamais réservé de cette facon, et j'ai jamais eu de problème
0
vecchio56 Messages postés 6535 Date d'inscription lundi 16 décembre 2002 Statut Membre Dernière intervention 22 août 2010 14
2 sept. 2005 à 11:58
Je viens d'essayer il refuse de mettre ca dans .stack:
"Code or data emission to undeclared segment"
0
cs_patatalo Messages postés 1466 Date d'inscription vendredi 2 janvier 2004 Statut Modérateur Dernière intervention 14 février 2014 2
2 sept. 2005 à 12:59
encore un truc pas bon:
mov ax, oldTimerSegment
mov es, ax
ip_:
jmp es:oldTimerOffset ; appel de la routine par défaut

devrait etre:
jmp far [oldTimerSegment]
0
vecchio56 Messages postés 6535 Date d'inscription lundi 16 décembre 2002 Statut Membre Dernière intervention 22 août 2010 14
2 sept. 2005 à 13:08
ah? Je connais pas, il me manque quelques notions on dirait. Mais oldTimerOffset qu'est ce qu'on en fait? C'est important quand même, il faut pas qu'il saute au début du segment...
0
Rejoignez-nous