Bonjour à tous.
Une machine (x86) qui bouterait sans OS, possède t'elle une pile en mémoire?
Faut il en "construire" une pour faire fonctionner une application sans OS?
D'avance, merci.
Bonjour à tous.
Une machine (x86) qui bouterait sans OS, possède t'elle une pile en mémoire?
Faut il en "construire" une pour faire fonctionner une application sans OS?
D'avance, merci.
Oui et oui
le registre de segment de pile SS et le pointeur de pile SP
pointent forcément quelque part, donc on peut empiler/dépiler
Par contre, il faut faire attention d'initialiser correctement la pile
pour ne pas écraser ni code ni données
Dans un programme DOS .COM le segment de pile, le segment
de code, et le segment de données ont la même valeur (SS=CS=DS)
Et le pointeur de pile est en général initialisé avec une valeur proche
de la fin du segment.
Lors de l'empilage d'une valeur 16 bits, SP est décrémenté de 2 octets.
La pile se "remplie" à l'envers.
Chaque appel à un sous-programme utilise la pile, les interruptions
logicielles ou matérielles utilisent la pile... on ne peut y échapper
Salut,
Au démarrage de l'ordinateur un processeur de la famille x86 fonctionne en real mode et ses registres sont initialés à des valeur précises. Pour un programmeur il est préférable de les remplacer par ses propres valeurs, donc définir une pile !
(Tel qu'il est le cas dans un Bootscetor)
Dernière modification par Invité ; 28/05/2013 à 17h30.
Bonjour à tous.
Merci pour ces éclaircissements.
Dans le même registre (sans mauvais jeu de mot), est il vrai qu' on ne peut pas utiliser l'instruction RET car celle ci n'est utilisable qu'avec un OS en mémoire?
D'avance, merci.
Oui on peut utiliser les instructions CALL/RET, puisqu'on a déjà la pile du programme
principal (le programme appelant) !
à partir du moment où ton programme tourne sur une machine sans OS...
il devient lui-même un OS puisque tu utilises ta machine avec
Une fois que tu as initialisé la pile système, il n'y a pas de soucis à utiliser
des CALL/RET, des PUSH/POP etc...
Bonjour à tous.
Merci pour ces précisions.
Maintenant, ça me revient, j'avais lu ça quelque part. C'était pour un boot loader.
Donc si je comprend bien, on ne peut pas utiliser de RET, PUSH et POP dans un boot loader car la pile n'a pas était explicitement mise en place, c'est bien cela?
D'ailleurs, comment met on en place un pile? en donnant un valeur (une adresse) au SS et SP? Faut-il donner une taille? Si oui, comment?
D'avance merci.
Juste après le démarrage de l'ordinateur, le processeur exécute un JMP vers le routine BIOS. Comment ? Avec les processeurs 30486 et Pentium I et la famille P6 les registres CS et EIP sont initialisé comme suit : EIP = 0xFFF0 et CS = 0xFFFF0000 (Selector = 0xF000, Limit = 0xFFFF , Base = 0xFFFF0000). Voir chapitre 8 : tableau 1 dans ce manuel : http://communities.intel.com/servlet...rogramming.pdf
Ainsi, le processeur va exécuter l'instruction située à l'adresse 0xFFFFFFF0. C'est simplement un JMP vers le routine BIOS. Après les tests POST, le BIOS va chercher un disque bootable. Si il trouve un il charge le contenu de son bootsector (512 octets) dans la mémoire à l'adresse absolue 0x7C00. Le processeur commence l'exécution de cet adresse (CS:EIP = 0x7C0 : 0x0 => 0x7C0 x 0x10 0x7C00). Donc tu peut utiliser ce même segment de code comme segment de données et stack. C'est comme il a fait Linus Torvaldes dans le bootSector du noyau 0.01.
On est en real mode donc on peut choisir n'importe qu'elle zone mémoire pour créer le stack à condition qu'elle n'est pas réservée par INTEL ! La taille est automatiquement 64Ko et le SP pointe toujours vers le top de la pile, c-à-d l'avant dernier octets de SS.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 go: mov ax,cs mov ds,ax mov es,ax mov ss,ax mov sp,#0x400 | arbitrary value >>512
Bonsoir,
À l'origine, une pile est une structure de donnée purement abstraite, utilisée par les théories du traitement de l'information. Maintenant, les micro-processeurs en eux-mêmes sont pour ainsi dire tous dotés d'instructions permettant d'en exploiter une, et s'appuient eux-mêmes sur ces mécanismes.
Lorsque tu fais PUSH, le registre pointeur de pile (SP) est automatiquement décrémenté puis la valeur à empiler est déposée au nouvel endroit pointé. En ce sens, « PUSH AX », par exemple, est équivalent à :
POP est l'opération réciproque. Dans ce cas, on commence par récupérer la valeur pointée, puis on incrémente le registre. « POP AX » ce qui est équivalent à :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 SUB SP,2 MOV [SP],AX
Et maintenant que ces instructions existent, le micro-processeur lui-même va s'appuyer dessus. Lorsque tu fais un « CALL », le micro-processeur empile l'adresse de retour puis fait un saut à l'adresse indiquée. « CALL adresse » est donc équivalent à :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 MOV AX,[SP] ADD SP,2
Et pour finir, « RET » ne fait que dépiler une adresse mémoire préalablement empilée, en principe par CALL. « RET » est donc équivalent à :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 PUSH IP JMP adresse
On comprend qu'ainsi, on peut soi-même aller lire ou altérer une adresse de retour, voire même simuler un CALL. Il suffit d'écrire dans la pile comme on le ferait n'importe où ailleurs. Les debuggers utilisent beaucoup cette possibilité. C'est pratique également pour supprimer l'adresse de retour si on rencontre un cas qui nous amène à ne pas revenir (un exec() ou un exit(), par exemple).
Code : Sélectionner tout - Visualiser dans une fenêtre à part POP IP
Tout-à-fait.D'ailleurs, comment met on en place un pile? en donnant un valeur (une adresse) au SS et SP?
Non, parce que le micro-processeur ne fera pas plus de contrôle que ce que tu vois au dessus. Il peut même franchir le « 0000 » et revenir à la fin du plan mémoire, ça ne posera pas de problème s'il peut écrire dedans.Faut-il donner une taille? Si oui, comment?
Merci à vous pour toutes ces précisions! ça donne envie de faire un boot loader!
Encore une petite question:
Si un OS (DOS par exemple) est déjà en mémoire, dois-je définir ma propre plie pour faire exécuter mon programme ou bien puis-je (suis-je obligé?) d'utilisé celle de l'OS?
D'avance merci.
Un O.S., c'est un logiciel comme un autre. On lui donne le nom de « système d'exploitation » parce qu'il fournit et met en place les infrastructures qui permettent ensuite d'exécuter facilement des programmes sans avoir à tout réinventer à chaque fois, mais c'est de la même façon qu'un traitement de texte, par exemple, est un logiciel qui te permet de composer facilement des documents écrits.
Si tu travailles sous D.O.S., celui-ci te mettra lui-même une pile en place quelque part au moment où il lancera ton programme. Tu peux déplacer ton pointeur de pile ailleurs si tu le souhaites à condition de le restaurer à son état initial avant de quitter ton programme (sinon D.O.S. ne retrouvera plus ses petits), et de prévoir suffisamment de place pour tes besoins ET ceux du système (en prévoyant notamment les interruptions matérielles).
Si par contre tu travailles sur des systèmes plus évolués, par exemple Linux ou Windows en mode protégé et en 32 bits ou 64 bits, ce sera un poil plus compliqué car le système va effectuer allouer des zones de mémoire distinctes pour la pile, les données et le code. Tu pourras toujours modifier ton pointeur de pile si ça te chante mais seulement au sein du segment alloué, ce qui n'a pas beaucoup d'intérêt en soi. Si tu veux aller plus loin, il faudra passer en mode privilégié et expliquer tout cela au système. Et là, on n'est plus du tout dans la même catégorie…
Ok merci pour vos réponses.
Je résumes par écrit (ça m'aider à mémoriser ):
Je peut faire ma propre pile.
Je peut utiliser la pile de L'OS.
Il est fortement recommander d'utiliser la pile de l'OS.
Cordialement.
Flyinman, tu mettre ta pile n’importe ou tu veux en mémoire, un OS ne te permet pas de modifier ss:esp comme tu veux, Si besoin, il te faut passer par la routine du système te permettant de le faire.
Si tu bootre sur ton propre code, tun mets ta pile ou tu veux en mémoire, il faut faire attention à ce que ta pile n'écrase pas ton code exemple la fin de ton code se trouve à l'adresse 0x0010 ton registre de pile se trouve à l'adresse 0x0014 si tu fais push ax, sp va avoir comme valeur 0x12, un autre push ax : adresse 0x10, et enfin un autre : adresse 0x08 le code entre 0x0008 et 0x0010 va être remplacé par l'empilement donc va être écrasé.
Quand tu es en mode protégé, si tu crée un segment spécifique ou une page spécifique pour la pile, tu tu sors de la zone déterminée tu aura une exception.
Ma page sur developpez.com : http://chrtophe.developpez.com/ (avec mes articles)
Mon article sur le P2V, mon article sur le cloud
Consultez nos FAQ : Windows, Linux, Virtualisation
OK, merci encore. Je vais lire tout cela à tête reposée
Cordialement.
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager