Segment 16 bits [Résolu]

Messages postés
75
Date d'inscription
mardi 29 juillet 2008
Statut
Membre
Dernière intervention
25 mars 2019
-
Bonjour,

Voila,je n'arrive pas à utiliser une valeur issue du segment mémoire 0:... (zone des pointeurs sur les gestionnaire interruptions bios).
(mon but est d'afficher simplement ces différentes valeurs)

le code est compilé en .com par nasm (nasm -fbin prog.asm -o prog.com)
puis exécuter par dos box (je suis sous Windows 8)

voici le code;

org 100h

%define NumInt 2 ;n° de l'int voulue

section .txt

start:

mov ax,cs
mov ds,ax
mov ax,0B800h
mov es,ax ;es pointe sur ram video texte vga
mov ax,0
mov fs,ax ;fs pointe sur segment 0:....

mov ax,3 ;texte 80*25
int 10h

mov si,NumInt
shl si,2 ;dx pointe sur pointeur gestionnaire correspondant (NumInt*4)

mov ax,[fs:si] ;ax contient le word de l'offset du pointeur far
add al,30h ;al devient un code ascii affichable

mov ah,100b ;attribut couleur
mov di,0 ;première case vga texte

mov [es:di],ax ;ecriture en vga texte

mov ah,0
int 16h

ret

ce code m'affiche '8' alors qu'en traçant le code DWORD[0:4] vaut 0603h,je devrais donc avoir '3' d'afficher (03+30h=33h='3'.

qu'est ce qui ne va pas ?
Afficher la suite 

8 réponses

Meilleure réponse
1
Merci
re,

En plus de l'utilisation du segment fs (qui est apparu avec les processeurs 32 bits et qui pourrait donc être mal interprété par un émulateur 80x86), j'ajouterais que l'acces à la mémoire vidéo 0xB80000-0xBFFFF se faisait uniquement octet par octet.

De plus, sous dos, les interruptions étant modifiées aléatoirement (fonctionnement par surcharge), je te conseillerais de copier la table des vecteurs avant de travailler dessus. Surtout si tu verifies ton programme avec un debugger.

Dire « Merci » 1

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

Codes Sources 206 internautes nous ont dit merci ce mois-ci

Commenter la réponse de patatalo
1
Merci
Bonjour,

Oui d'une certaine manière. Ce que je veux dire c'est que chaque programme, TSR ou interruption a la possibilité de modifier la table afin de rediriger l'execution vers une routine personnelle. C'est a la routine et non au système de redonner la main au vecteur précédent. Cela génère une surcharge (Je crois que ça s'appelle comme cela). On dirait un "hook" en anglais (crochet) comme pour un trajet en voiture.

Bien sur, tout ceci n'est valable que quand l'interruption concerne un appel à une routine.

bon courage.

Dire « Merci » 1

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

Codes Sources 206 internautes nous ont dit merci ce mois-ci

Commenter la réponse de patatalo
0
Merci
salut,

DWORD[0:4] NON mais DWORD[0:2] !!!
DWORD = 2 WORD = 4 BYTE !!!
Commenter la réponse de patatalo
Messages postés
75
Date d'inscription
mardi 29 juillet 2008
Statut
Membre
Dernière intervention
25 mars 2019
0
Merci
Bonjour patatalo,

Merci pour ta réponse,je me suis effectivement trompé dans mon commentaire,je voulais écrire word[0:4] et pas dword[0:4]

Mais je n'ai toujours pas trouvé mon erreur dans mon code.
Ce que je ne comprend pas, c'est que lorsque je traçe mon code, les valeurs attendues sont les bonnes....

org 100h

%define NumInt 2 ;n° de l'int voulue

section .txt

start:

mov ax,cs
mov ds,ax
mov ax,0B800h
mov es,ax ;es pointe sur ram video texte vga
mov ax,0
mov fs,ax ;fs pointe sur segment 0:....

mov ax,3 ;texte 80*25
int 10h

mov si,NumInt
shl si,2 ;en traçant si=2*4=8

mov ax,[fs:si] ;en traçant ax=0603h
add al,30h ;al=33h

mov ah,4 ;attribut couleur (ici ax=0433h)
mov di,0 ;première case vga texte

mov [es:di],ax ;ecriture en vga texte

mov ah,0
int 16h

ret


ce code m'affiche un '8' ????? au lieu d'un '3'
ce qui me fait m'arracher les cheveux, c'est qu' en traçant j'ai les bonnes valeurs, et que si je fourni moi même la valeur du caractère ascii à afficher, ça marche.

org 100h

%define NumInt 2 ;n° de l'int voulue

section .txt

start:

mov ax,cs
mov ds,ax
mov ax,0B800h
mov es,ax ;es pointe sur ram video texte vga
mov ax,0
mov fs,ax ;fs pointe sur segment 0:....

mov ax,3 ;texte 80*25
int 10h

mov al,'A' ;je fourni moi même le code

mov ah,100b ;attribut couleur
mov di,0 ;première case vga texte

mov [es:di],ax ;ecriture en vga texte

mov ah,0
int 16h

ret

Et là, ça m'affiche bien 'A'.

Le problème vient t'il de la manipulation de plusieurs segments de données ?


--
Bonjour,
Sans doute n'ai-je pas tout compris au problème qui vous tracasse, mais je vous propose l'explication suivante.
Je passerai rapidement sur la curieuse obstination à utiliser le registre de segment FS alors que vous avez DS à votre disposition, ni sur l'inversion "DWORD=2 bytes alors que WORD=4 bytes", puisque c'est exactement l'inverse ! La suite devrait montrer que cette inversion ne doit pas être exemptée d'un rapport avec votre erreur.
A l'analyse de votre source je n'ai eu aucun reproche à faire, je l'ai donc assemblé comme vous et avec moi il a fonctionné parfaitement.
Par contre, ce programme affiche ( approximativement ) le byte de poids faible de la partie offset du vecteur d'interruption N°2, et contrairement à ce que vous semblez croire, l'adresse de ce byte est 0:8 et non 0:4. Si vous faite un dump de la table des vecteurs d'interruption vous trouverez sans doute en 0:8 un octet du type xxxx1000b et en 0:4 un octet du type xxxx0011b.
Cordialement.
Commenter la réponse de cs_parki
Messages postés
75
Date d'inscription
mardi 29 juillet 2008
Statut
Membre
Dernière intervention
25 mars 2019
0
Merci
Bonjour PYRHON,

Merci de m'avoir répondu.

Vous me dites que le code suivant affiche bien la dernière lettre hexa de l'offset du pointeur de l'int 2h de votre bios ? (cad affiche par ex '4' si l'offset est xxx4h ?)

org 100h
section .txt
start:

mov ax,cs
mov ds,ax
mov ax,0B800h
mov es,ax ;es pointe sur ram video texte vga
mov ax,0
mov fs,ax ;fs pointe sur segment 0:....

mov ax,3 ;texte 80*25
int 10h

mov si,8 ;offset du pointeur sur le gestionnaire de int 2

mov ax,[fs:si] ;en traçant ax=0603h
add al,30h ;al=33h

mov ah,4 ;attribut couleur (ici ax=0433h)
mov di,0 ;première case vga texte

mov [es:di],ax ;ecriture en vga texte

mov ah,0
int 16h

ret


Car sur mon pc où l'offset est 0603h,cela m'affiche toujours '8' .

(je me prends la tête avec cela car j'aimerais simplement faire
un prog qui affiche les adresses des gestionnaires d'int)


ps: voilà ce que j'ai compris pour les adresses des pointeurs des int;

la table des pointeurs des gestionnaires d'interruptions commence en 0:0
Chaque pointeurs est formé de 2 words(=1 dword)
Le premier word se situe en 0+(n° de INT *4) est correspond à l'offset du pointeur.
Le second word qui suit le premier correspond au segment du pointeur.
Donc pour l'int 2h,premier word (=offset) en 0:8 (=byte[0:8] et byte [0:9]) ,second word (=segment) en 0:10 (= byte[0:10] et byte [0:11])

Est ce exact ?















--
Commenter la réponse de cs_parki
Messages postés
75
Date d'inscription
mardi 29 juillet 2008
Statut
Membre
Dernière intervention
25 mars 2019
0
Merci
Bonjour,

Effectivement PHYRON,
C'est un problème d'émulation sous dos box + Windows 8
J'ai testé le prog en V86 sous xp et ça marche.

Merci pour vos réponses,

Bonne prog.


--
Commenter la réponse de cs_parki
Messages postés
75
Date d'inscription
mardi 29 juillet 2008
Statut
Membre
Dernière intervention
25 mars 2019
0
Merci
Bonjour patatalo,

merci pour ta réponse.

Qu' est ce que cela signifie un fonctionnement par surcharge ?
Tu veux dire que les adresses des gestionnaires d'interruption varient en fonction de l'occupation de la mémoire ?



--
Commenter la réponse de cs_parki
Messages postés
75
Date d'inscription
mardi 29 juillet 2008
Statut
Membre
Dernière intervention
25 mars 2019
0
Merci
merci pour ta réponse patatalo

( ça y est , j'ai compris : chaque prog peut détourner une int d'où les adresses des vecteurs peuvent varier suivant les prog en cours.
D'où ton conseil de sauvegarder la totalité de la table avant de travailler dessus.)

Bonne prog.





--
Commenter la réponse de cs_parki