Segment 16 bits

Résolu
cs_parki Messages postés 75 Date d'inscription mardi 29 juillet 2008 Statut Membre Dernière intervention 25 mars 2019 - Modifié par cs_parki le 17/10/2013 à 12:47
cs_parki Messages postés 75 Date d'inscription mardi 29 juillet 2008 Statut Membre Dernière intervention 25 mars 2019 - 31 oct. 2013 à 15:48
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 ?

8 réponses

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.
1
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.
1
salut,

DWORD[0:4] NON mais DWORD[0:2] !!!
DWORD = 2 WORD = 4 BYTE !!!
0
cs_parki Messages postés 75 Date d'inscription mardi 29 juillet 2008 Statut Membre Dernière intervention 25 mars 2019
21 oct. 2013 à 14:42
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 ?


--
0
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.
0

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

Posez votre question
cs_parki Messages postés 75 Date d'inscription mardi 29 juillet 2008 Statut Membre Dernière intervention 25 mars 2019
Modifié par cs_parki le 25/10/2013 à 17:20
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 ?















--
0
cs_parki Messages postés 75 Date d'inscription mardi 29 juillet 2008 Statut Membre Dernière intervention 25 mars 2019
27 oct. 2013 à 11:37
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.


--
0
cs_parki Messages postés 75 Date d'inscription mardi 29 juillet 2008 Statut Membre Dernière intervention 25 mars 2019
30 oct. 2013 à 16:56
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 ?



--
0
cs_parki Messages postés 75 Date d'inscription mardi 29 juillet 2008 Statut Membre Dernière intervention 25 mars 2019
31 oct. 2013 à 15:48
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.





--
0
Rejoignez-nous