À quoi servent les instructions D'entrée et de sortie dans x86?

j'ai encodé ces instructions dans et hors tout en lisant le livre" Comprendre le noyau Linux". J'ai regardé le manuel de référence.

5.1.9 Instructions D'E/S

ces instructions déplacent les données entre les ports E/S du processeur et un registre ou mémoire.

IN    Read from a port
OUT   Write to a port
INS/INSB  Input string from port/Input byte string from port 
INS/INSW  Input string from port/Input word string from port 
INS/INSD  Input string from port/Input doubleword string from port
OUTS/OUTSB    Output string to port/Output byte string to port 
OUTS/OUTSW    Output string to port/Output word string to port 
OUTS/OUTSD    Output string to port/Output doubleword string to port

je n'ai pas peu de choses:

  1. " processeurs Ports d'e/S". Quels sont-ils? Pourquoi voulons-nous lire & écrire "strings" vers & à partir de ces ports?
  2. Je n'ai jamais encouté de scénario où je dois utiliser ces instructions. Quand aurais-je besoin?
  3. Donner quelques exemples pratiques.
46
demandé sur claws 2010-07-09 23:23:51

7 réponses

vous savez comment fonctionne l'adressage de la mémoire? Il y a un bus d'adresse, un bus de données, et quelques lignes de contrôle. Le CPU met l'adresse d'un octet (ou d'un octet de début) de mémoire sur le bus d'adresse, puis lève le signal de lecture, et une puce de mémoire RAM retourne avec espoir le contenu de la mémoire à cette adresse en élevant ou en abaissant des lignes individuelles (correspondant à des bits dans le(s) octet (s)) sur le bus de données. Cela fonctionne pour RAM et ROM.

mais il y a aussi des dispositifs d'e/s: Ports série et parallèles, le pilote pour le petit haut-parleur interne D'un PC, les contrôleurs de disque, les puces de son et ainsi de suite. Et ces appareils obtiennent également lu et écrit à. Ils doivent également être pris en compte pour que le CPU accède au périphérique correct et (généralement) à l'emplacement correct des données dans un périphérique donné.

pour certains modèles de CPU, y compris la série xxx86 que l'on trouve dans la plupart des PC" modernes", les périphériques d'e/s partagent l'espace d'adresse avec la mémoire. Les périphériques RAM / ROM et IO sont connectés la même adresse, les données et les lignes de contrôle. Par exemple, le port série pour COM1 est adressé à partir de (hex) 03F8. Mais il y a certainement de la mémoire à la même adresse.

voici un diagramme très simple:

[ https://qph.ec.quoracdn.net/main-qimg-e510d81162f562d8f671d5900da84d68-c?convert_to_webp=true ]

il est clair que le CPU a besoin de parler à la mémoire ou au périphérique D'E/S, jamais aux deux. Pour distinguer les deux, une des lignes de contrôle appelée "M / #IO" affirme si le CPU veut pour parler à la mémoire (ligne=haute) ou à un périphérique D'E/S (ligne=basse).

l'instruction dans lit d'un appareil d'e/s, écrit. Lorsque vous utilisez les instructions D'entrée ou de sortie, le M/#IO n'est pas affirmé (tenu bas), donc la mémoire ne répond pas et la puce d'entrée/sortie le fait. Pour les instructions axées sur la mémoire, M / #IO est affirmé de sorte que le CPU parle à la mémoire vive, et les dispositifs D'IO restent en dehors de la communication.

dans certaines conditions, les dispositifs IO peuvent entraîner les lignes de données et le RAM peut les lire en même temps. Et vice-versa. Ça s'appelle DMA.

traditionnellement, les ports série et imprimante, ainsi que le clavier, la souris, les capteurs de température et ainsi de suite étaient des dispositifs D'e/s. Les disques se trouvaient en quelque sorte entre les deux; les transferts de données étaient amorcés par des commandes D'E/S, mais le contrôleur de disques déposait habituellement ses données directement dans la mémoire du système.

dans les systèmes d'exploitation modernes comme Windows ou Linux, l'accès aux ports E/S est caché de les programmes utilisateurs "normaux", et il y a des couches de logiciels, des instructions privilégiées et des pilotes pour traiter avec le matériel. Donc, au cours de ce siècle, la plupart des programmeurs ne s'occupent pas de ces instructions.

70
répondu Carl Smotricz 2017-01-11 06:28:51

commence par quelque chose comme ceci:

http://www.cpu-world.com/info/Pinouts/8088.html

vous apprenez des instructions pour une technologie très ancienne puce/architecture. Quand tout sauf le processeur était hors circuit. Voir les lignes d'adresse et les lignes de données et il y a une ligne de lecture RD et une ligne d'écriture WR et une ligne IO/M?

il y avait deux types d'instructions basées sur la mémoire et l'E/S basé parce qu'il y avait des espaces adressables, facilement décodés par L'IO/Mo IO ou la mémoire.

rappelez-vous que vous aviez 74LSxx colle logique, beaucoup de fils et beaucoup de puces pour connecter une mémoire au processeur. Et la mémoire était juste cette mémoire, de grosses puces chères. Si vous aviez un périphérique qui avait besoin de faire quelque chose d'utile vous aviez aussi des registres de contrôle, la mémoire pourrait être des données de pixel, mais quelque part vous aviez besoin de définir les limites horizontales et verticales des horloges de balayage, ceux-ci pourraient être chaque 74lsxx verrous, pas de souvenirs, ayant I/O mapped I / O enregistré sur la logique de colle et juste fait beaucoup de sens d'un point de vue programmeur il a également évité de changer vos registres de segment pour diriger votre fenêtre de mémoire de 64K autour, etc. L'espace d'adresse de mémoire était une ressource sacrée, surtout quand vous vouliez limiter votre décodage d'adresse à quelques bits parce que chaque peu de bits vous coûtent un certain nombre de puces et de fils.

Like big and little endian memory mapped I/O vs I/O mapped I / O a été une guerre de religion. Et certaines des réponses que vous allez voir à votre question, va refléter la forte opinions qui sont encore aujourd'hui dans les gens qui les ont vécus. La réalité est que chaque puce sur le marché aujourd'hui a busess multiples pour diverses choses, vous dont accrocher votre horloge en temps réel hors du bus mémoire ddr avec un décodeur d'adresse. Certains ont même encore des bus d'instruction et de données complètement séparés. Dans un sens Intel a gagné la guerre pour le concept d'adresse séparée espaces pour différentes classes de choses même si le terme I/O port est mauvais et mauvais et ne devrait pas être prononcé pour dire 20-30 années de plus. Vous avez besoin de gens de mon âge qui l'ont vécu pour être à la retraite ou parti avant que la guerre soit vraiment terminée. Même le terme mémoire cartographiée e / s est une chose du passé.

C'est vraiment tout ce que ça a toujours été, un seul bit de décodage d'adresse sur l'extérieur de la puce intel qui était contrôlé par l'utilisation d'instructions spécifiques. Utilisez une série d'instructions était en cours d'utilisation un ensemble d'instructions le morceau était éteint. Vous voulez voir quelque chose d'intéressant allez voir le jeu d'instructions pour les processeurs xcore xmos ils ont beaucoup de choses qui sont des instructions au lieu de registres de mappage de mémoire, il prend cette chose I/O mapped I/O à un tout nouveau niveau.

où il a été utilisé est comme je l'ai décrit ci-dessus, vous mettiez des choses qui avaient du sens et vous pourriez vous permettre de brûler l'espace d'adresse de mémoire pour comme les pixels vidéo, la mémoire de paquet de réseau (peut-être), mémoire de carte de son (bien pas que l'un ou l'autre mais vous pourriez avoir), etc. Et les registres de contrôle, l'espace d'adresse par rapport aux données était très petit, peut-être seulement quelques registres, ont été décodés et utilisés dans l'espace D'e/s. les plus évidents sont/étaient les ports série et les ports parallèles qui avaient peu ou pas de stockage, vous auriez pu avoir un petit fifo sur le port série.

parce que l'espace d'adresse était rare, il n'était pas rare et est encore vu aujourd'hui pour avoir la mémoire cachée derrière deux registres un registre d'adresses et un registre de données, cette mémoire n'est disponible que via ces deux registres, elle n'est pas mappée en mémoire. donc vous écrivez l'offset dans cette mémoire cachée dans le registre d'adresses et vous lisez ou écrivez le registre de données pour accéder au contenu de la mémoire. Maintenant, parce que intel avait l'instruction rep et vous pourriez le combiner avec insb/W outsb/w le décodeur de matériel serait (si vous aviez des gens de matériel sympa / amical travaillant avec vous) auto-oincrément l'adresse à chaque fois que tu as fait un cycle d'entrées/sorties. Ainsi, vous pourriez écrire l'adresse de départ dans le registre d'adresses et faire un rep outsw et sans burning fetch et decode cycles d'horloge dans le processeur et sur le bus de mémoire vous pourriez déplacer des données assez rapidement dans ou hors du périphérique. Ce genre de chose est maintenant considéré comme un défaut de conception grâce aux processeurs modernes super scalar avec des fetches basées sur la prédiction de branche, votre matériel peut faire l'expérience lit à tout moment qui n'ont rien à voir avec l'exécution de code, comme un résultat vous ne devriez jamais auto incrémenter une adresse ou effacer des bits dans un registre de statut ou modifier quoi que ce soit à la suite d'une lecture à une adresse.

les mécanismes de protection intégrés dans le 386 et sur le présent rendent en fait très facile d'accéder à l'E/S à partir de l'espace de l'utilisateur. Selon ce que vous faites pour gagner votre vie, ce que votre entreprise produit, etc. Vous pouvez très certainement utiliser la famille in and out des instructions de l'espace utilisateur (programmes d'application sous windows et linux, etc.) ou l'espace noyau/pilote, c'est votre choix. Vous pouvez aussi faire des choses amusantes comme profiter de la machine virtuelle et utiliser les instructions d'E/S pour parler aux pilotes, mais cela énerverait probablement les gens à la fois dans les mondes windows et linux, Ce pilote/application ne le ferait pas très loin. Les autres affiches sont correctes en ce sens que vous n'aurez probablement jamais besoin d'utiliser ces instructions à moins que vous n'écriviez des pilotes, et vous n'écrirez probablement jamais des pilotes pour des périphériques utilisant I/O mapped I / O parce que vous savez...les pilotes des périphériques existants ont déjà été écrits. Les conceptions modernes ont très certainement I/O mais il est toute la mémoire mappée (du point de vue des programmeurs) et utilise des instructions de mémoire pas I / O instructions. Maintenant, L'autre côté si C'est DOS n'est certainement pas mort, selon l'endroit où vous pouvez construire des machines de vote ou des pompes à essence ou des caisses enregistreuses ou une longue liste D'équipements basés DOS. En fait, si vous travaillez dans un endroit qui construit des Périphériques Pc ou PC ou les cartes mères, les outils basés sur DOS sont encore largement utilisés pour tester et distribuer les mises à jour de BIOS et autres choses similaires. Je me retrouve encore dans des situations où je dois prendre le code d'un programme de test dos en cours pour écrire un pilote linux. Tout comme tout le monde qui peut jeter ou attraper un football joue dans la NFL, pourcentage sage très peu font le travail de logiciel qui implique ce genre de choses. Donc, il est encore sûr de dire que ces instructions que vous avez trouvé ne vont probablement pas être plus que leçon d'histoire.

22
répondu old_timer 2016-11-14 15:06:22

donner quelques exemples pratiques.

premier apprendre à:

puis:

  1. PS / 2 controller : récupérez l'ID scancode du dernier caractère tapé sur le clavier à al :

    in "151900920"x60, %al
    

    exemple Minimal

  2. Horloge Temps Réel (RTC) : obtenir le mur du temps avec la définition de secondes:

    .equ RTCaddress, 0x70
    .equ RTCdata, 0x71
    
    /* al contains seconds. */
    mov "151910920", %al
    out %al, $RTCaddress
    in $RTCdata, %al
    
    /* al contains minutes. */
    mov "151910920"x02, %al
    out %al, $RTCaddress
    in $RTCdata, %al
    
    /* al contains hour. */
    mov "151910920"x04, %al
    out %al, $RTCaddress
    

    exemple Minimal

  3. Programmable Interval Timer (PIT) : générer une interruption numéro 8 chaque 0x1234 / 1193181 secondes:

    mov "151920920"b00110100, %al
    outb %al, "151920920"x43
    mov "151920920"xFF, %al
    out %al, "151920920"x34
    out %al, "151920920"x12
    

    exemple Minimal

    Un noyau Linux 4.2 utilisation de la . Il en existe d'autres.

testé sur: qemu 2.0.0 Ubuntu 14.04, et real hardware Lenovo ThinkPad T400.

Comment faire trouver les numéros de port: y a-t-il une spécification de x86 I/O port assignment?

https://github.com/torvalds/linux/blob/v4.2/arch/x86/kernel/setup.c#L646 a une liste de nombreux ports utilisés par le noyau Linux.

autres architectures

toutes les architectures n'ont pas de telles instructions.

Dans les BRAS par exemple, IO est fait simplement en écrivant à magic hardware les adresses mémoire définies.

je pense que c'est ce que https://stackoverflow.com/a/3221839/895245 means by"memory mapped I/O vs I/O mapped I/O".

du point de vue du programmeur, je préfère la méthode ARM, car les instructions IO ont déjà besoin d'adresses magiques pour fonctionner, et nous avons d'énormes espaces d'adresse inutilisés dans l'adressage 64 bits.

voir https://stackoverflow.com/a/40063032/895245 pour un exemple de bras en béton.

10

si vous n'écrivez pas un système d'exploitation, vous n'utiliserez jamais ces instructions.

Les machines

x86 ont deux espaces d'adresse indépendants - l'espace d'adresse mémoire que vous connaissez, puis l'espace d'adresse e / s Les adresses de ports D'E/S ne font que 16 bits de large, et renvoient aux registres de bas niveau et autres widgets de bas niveau qui font partie d'un périphérique d'E / S-quelque chose comme un port série ou parallèle, un contrôleur de disque, etc.

là sont pas des exemples pratiques, car ils sont également utilisés par les pilotes de périphériques et systèmes d'exploitation.

3
répondu John Saunders 2010-07-09 19:37:36

au niveau matériel, la plupart des microprocesseurs ont peu ou pas de capacité d'E/S intégrée. Quelques processeurs ont une ou plusieurs broches qui peuvent être activées et désactivées en utilisant des instructions spéciales, et/ou une ou plusieurs broches qui peuvent être testées en utilisant des instructions spéciales de branche, mais de telles caractéristiques sont rares. Au lieu de cela, l'entrée / sortie est généralement gérée par le câblage du système de sorte que les accès à une gamme d'adresses mémoire va déclencher un certain effet, ou en incluant" in "et" out " instructions qui se comportent comme la mémoire charge / stocke les opérations sauf qu'un signal spécial est sortie disant "Ceci est une opération d'E/S au lieu d'une opération de mémoire."À l'époque des processeurs 16 bits, il y avait de réels avantages à avoir des instructions spécialisées. De nos jours, de tels avantages sont largement discutables car on pourrait simplement attribuer une grande partie de son espace d'adresse à l'E/S et il en reste encore beaucoup pour la mémoire.

Puisqu'un programme pourrait faire des ravages considérables sur un système par des instructions d'E/S mal exécutées (par exemple, de telles instructions pourraient effectuer des accès arbitraires au disque), tous les systèmes d'exploitation modernes interdisent l'utilisation de telles instructions dans le code de l'utilisateur. Certains systèmes peuvent permettre que de telles instructions soient virtualisées; si le code utilisateur essaie d'écrire aux ports d'entrée/sortie 0x3D4 et 0x3D5, par exemple, un système d'exploitation pourrait interpréter cela comme une tentative de définir des registres de contrôle de contrôle vidéo pour déplacer le curseur clignotant. Chaque fois que l'utilisateur programme effectué le l'instruction, le système d'exploitation prendrait la relève, verrait ce que le programme de l'utilisateur essayait de faire, et agir de manière appropriée.

dans la grande majorité des cas, même si le système d'exploitation traduisait une instruction D'entrée ou de sortie en quelque chose de convenable, il serait plus efficace de demander directement au système d'exploitation l'action appropriée.

3
répondu supercat 2010-07-09 20:28:58

il y a un peu plus de ruse que ça. Il ne se contente pas de multiplexer un espace d'adresse séparé de 64kb sur les mêmes fils avec un "bus d'adresse supplémentaire/chip select pin". Intel 8086 et 8088 et leurs clones multiplexent également le bus de données et le bus d'adresse; tous des choses très rares dans les CPU. Les feuilles de données sont pleines de trucs de configuration "minimum/maximum" et tous les registres de verrouillage que vous devez brancher pour le faire se comporter "normalement". D'autre part, il permet d'économiser la charge et portes et " ou "de l'une des portes de décodage d'adresses et de 64 ko devrait être "assez de ports d'e/s pour tous": P

aussi, pour tous ces 'développeurs pilotes seulement' Personnes, prendre note: outre les gens qui utilisent des puces compatibles Intel dans d'autres matériels que les PCs (ils n'ont jamais été vraiment destinés à l'utilisation dans le PC IBM en premier lieu - IBM vient de les prendre parce qu'ils étaient bon marché et déjà sur le marché), Intel vend également des microcontrôleurs avec le même ensemble d'instructions (Intel Quark) et il ya beaucoup de systèmes sur une puce " par d'autres fournisseurs avec le même jeu d'instructions. Je ne pense pas que vous arriverez à créer quoi que ce soit avec 'user space' '' kernel 'et' drivers ' séparés en 32kb :). Pour la plupart des choses, de tels "systèmes d'exploitation" complexes ne sont ni optimaux ni souhaités. Former des paquets UDP en RAM et ensuite les mettre dans un tampon annulaire et faire claquer des relais ne nécessite pas un noyau de 30 Mo et un temps de chargement de 10 secondes, vous savez. En gros, c'est le meilleur choix dans le cas où un microcontrôleur PIC n'est pas tout à fait suffisant, mais vous ne voulez pas d'un PC industriel entier. Les instructions d'entrée/sortie du port sont donc très utilisées et pas seulement par les "développeurs pilotes" pour les systèmes d'exploitation plus grands.

1
répondu HRH Sven Olaf von CyberBunker 2017-08-17 22:47:34

CPU connecté à certains contrôleurs externes via les ports io. sur l'ancien pc x86 je travaille avec le lecteur de disquettes en utilisant les ports D'e/s. si vous savez quelles commandes acceptent device controller vous pouvez le programmer à travers ses ports.

dans le monde moderne, vous n'utiliserez jamais les instructions de ports. Exception si vous êtes (ou serez) le développeur de drivers.

il y a des informations plus détaillées sur les ports d'entrée/sortie http://webster.cs.ucr.edu/AoA/DOS/ch03/CH03-6.html#HEADING6-1

0
répondu Evgen Bodunov 2010-07-09 19:36:10