Question

Je lis sur la mémoire d'adressage. Je l'ai lu le segment offset et ensuite sur les descripteurs OFFSET. Je sais comment calculer les adresses exactes en mode réel. Tout cela est OK, mais je suis incapable de comprendre ce qui est exactement compensé? Partout où je lis:

  

En mode réel, les registres ne sont que 16 bits de sorte que vous ne pouvez adresser   jusqu'à 64k. Afin de permettre de traiter plus de mémoire, adresse קד sont   calculée à partir de segments * 16 + offset.

Ici, je peux comprendre la première ligne. Nous avons 16 bits, afin que nous puissions adresser jusqu'à 2 ^ 16 = 64k.

Mais quelle est cette deuxième ligne? Qu'est-ce que le segment représentent? Pourquoi nous multiplions avec 16? pourquoi nous ajouter un DÉCALAGE. Je ne peux pas comprendre ce que ce décalage est? Quelqu'un peut-il me expliquer ou me donner le lien pour cette s'il vous plaît?

Était-ce utile?

La solution

Sous x86 en mode réel mémoire l'adresse physique est de 20 bits de long et est calcolated:

PhysicalAddress = Segment * 16 + Offset

Consultez aussi: en mode réel Gestion de la mémoire

Autres conseils

Quand Intel a construit le 8086, il y avait un cas valable pour avoir plus de 64 Ko dans une machine, mais il n'y avait aucun moyen qu'il ait jamais utiliser un espace d'adressage 32 bits. À l'époque, même un méga-octet était beaucoup de mémoire. (Rappelez-vous la citation infâme « 640K devrait être suffisant pour tout le monde »? Il est essentiellement une traduction erronée du fait qu'à l'époque, 1MB flippait énorme .) Le mot « gigaoctet » ne serait pas en commun utilisation pendant 15-20 ans, et il ne serait pas référence à la RAM comme pour un autre 5-10 ans après.

Ainsi, au lieu de mettre en place un espace d'adressage si énorme qu'il avait « jamais » être pleinement utilisé, ce qu'ils ont fait était de mettre en œuvre les adresses 20 bits. Ils encore utilisé des mots de 16 bits pour les adresses, car après tout, cela est un processeur 16 bits. Le mot supérieur est le « segment » et le mot inférieur est le « décalage ». Les deux parties se chevauchent considérablement, bien que - un « segment » est un bloc de 64 Ko de mémoire qui commence à (segment) * 16, et le « décalage » peuvent pointer n'importe où à l'intérieur de ce morceau. Afin de calculer l'adresse réelle, vous multiplier la partie de segment de l'adresse de 16 (ou le déplacer à gauche de 4 bits ... même chose), puis ajouter le décalage. Lorsque vous avez terminé, vous avez une adresse de 20 bits.

 19           4  0
  +--+--+--+--+
  |  segment  |
  +--+--+--+--+--+
     |   offset  |
     +--+--+--+--+

Par exemple, si le segment était 0x8000, et le décalage étaient 0x0100, l'adresse réelle sort à ((0x8000 << 4) + 0x0100) == 0x80100.

   8  0  0  0
      0  1  0  0
  ---------------
   8  0  1  0  0

Le calcul est rarement propre, bien - 0x80100 peut être représenté par des milliers de différents segments:. Combinaisons de décalage (4096, si mes calculs sont à droite)

Je veux ajouter une réponse ici parce que je suis récuré l'Internet à essayer de comprendre cela aussi. Les autres réponses quittaient un élément clé de l'information que je ne reçois du lien présenté dans l'une des réponses. Cependant, je presque totalement raté. La lecture de la page liée, je ne comprenais pas encore comment cela fonctionnait.

Le problème que je me suis sans doute était de rencontre des seulement vraiment comprendre comment le Commodore 64 (6502 processeur) disposé mémoire. Il utilise une notation similaire à la mémoire d'adresse. Il a 64k de mémoire totale, et utilise des valeurs 8 bits de PAGE: OFFSET à la mémoire d'accès. Chaque page est de 256 octets de long (nombre de 8 bits) et les points de décalage à l'une des valeurs de cette page. Les pages sont espacés dos à dos dans la mémoire. Donc, page 2 commence là où la page 1 se termine. J'allais dans le 386 penser le même style. Ce n'est pas.

Le mode réel utilise un style similaire, même si elle est différente SEGMENT libellé: OFFSET. Un segment est 64k en taille. Cependant, les segments eux-mêmes ne sont pas disposés dos à dos comme le Commodore était. Elles sont espacées de 16 octets les uns des autres. Offset fonctionne toujours le même, ce qui indique le nombre d'octets de la page \ démarrage du segment.

J'espère que cette explication aide quelqu'un d'autre qui trouve cette question, il m'a aidé à écrire.

Je peux voir la question et les réponses sont quelques années, mais il y a une mauvaise déclaration qu'il n'y a que 16 registres de bits existent dans le mode réel.

Dans le mode réel les registres ne sont pas seulement 16 bits, car il y a aussi 8 registres de bits aussi. Chaque de ces registres à 8 bits est une partie d'un registre de 16 bits qui sont divisés en une partie inférieure et une partie supérieure d'un registre de 16 bits.

Et à partir du mode réel avec un 80386+ nous devenons 32 registres de bits et d'autres également deux nouveaux préfixes d'instruction, un pour à override / inverse par défaut opérande taille et un pour à override / inverser la valeur par défaut adresse taille d'un instruction à l'intérieur d'un segment de code.

Ces préfixes d'instruction peuvent être utilisés en combinaison pour inverser l'opérande taille et l'adresse de taille ainsi que pour une instruction. Au sein du mode réel par défaut opérande taille et l'adresse de taille est de 16 bits. Avec ces deux préfixes d'instruction, nous pouvons utiliser un opérande 32 bits / register exemple pour calculer une valeur 32 bits dans un registre 32 bits, ou pour se déplacer d'une valeur de 32 bits à partir d'un emplacement et memmory. Et nous pouvons utiliser tous les 32 registres de bits (peut-être en combinaison avec une base + indice * échelle + déplacement) comme une adresse registre, mais la somme de l'adresse effective ne doit pas être supérieure à la limite du segment taille 64 kb .

(Sur la OSDEV-Wiki page que nous pouvons trouver dans la table pour la « Opérande-size et préfixe override adresse grandeur » que le « 0x66 préfixe opérande » et le « préfixe 0x67 adresse » est N / A (non aviable ) pour le mode réel et le mode 8086 virtuel. http://wiki.osdev.org/X86-64_Instruction_Encoding
Mais cela est totalement faux, parce que dans le manuel Intel, nous pouvons trouver cette déclaration. « Ces préfixes peuvent être utilisés en mode d'adresse réelle, ainsi que dans le mode protégé et le mode virtuel 8086 »)

À partir d'un Pentium MMX nous devenons huit 64 bits MMX-registres.
A partir d'un Pentium 3, nous devenons huit 128 bits XMM-registres.
..

Si je ne me trompe pas, le 256 bit YMM-registre et le ZMM-Register 512 bits et 64 bits à usage général d'un registre 64 bits ne peut pas être utilisé dans le mode réel.

Dirk

Exemple minimal

  • offset = msg
  • Segment = ds
mov $0, %ax
mov %ax, %ds
mov %ds:msg, %al
/* %al contains 1 */

mov $1, %ax
mov %ax, %ds
mov %ds:msg, %al
/* %al contains 2: 1 * 16 bytes forward. */

msg:
.byte 1
.fill 15
.byte 2

Donc, si vous voulez la mémoire d'accès ci-dessus 64k:

mov $0xF000, %ax
mov %ax, %ds

Notez que cela permet pour les adresses de plus de 20 bits de large si vous utilisez quelque chose comme:

0x10 * 0xFFFF + 0xFFFF == 0x10FFEF

Sur les processeurs précédents qui avaient seulement 20 fils d'adresse, il était tout simplement tronquée, mais plus tard les choses se sont compliquées avec la ligne A20 (21 fils d'adresse): https://en.wikipedia.org/wiki/A20_line

GitHub repo avec le nécessaire boilerplate pour l'exécuter.

Un registre de 16 bits ne peut adresser jusqu'à 0xFFFF (65536 octets, 64KB). Lorsque cela ne suffisait pas, Intel a ajouté des registres de segment.

Toute conception logique aurait simplement combiné deux registres de 16 bits pour faire un espace d'adressage 32 bits, (par exemple 0xFFFF : 0xFFFF = 0xFFFFFFFF), mais nooooo ... Intel a dû faire tout bizarre sur nous.

Par le passé, le bus frontside (FSB) avait seulement 20 lignes d'adresse, et donc ne pouvait transmettre les adresses 20 bits. "rectifier" cela, Intel a conçu un système dans lequel des registres de segment ne couvrent que votre adresse de 4 bits (16 bits + 4 = 20, en théorie).

Pour ce faire, le registre de segment est décalé à gauche à partir de sa valeur d'origine par 4 bits, puis ajoutés à l'adresse dans le registre général (par exemple. [es:ax] = ( es << 4 ) + ax) . Remarque:. Décaler à gauche de 4 bits est équivalente à la multiplication par 16

Voilà. Voici quelques exemples:

;; everything's hexadecimal

[ 0:1 ] = 1

[ F:1 ] = F1

[ F:0 ] = F0

[ F:FF] = 1EF ; [F becomes F0, + FF = 1EF]

[ F000 : FFFF ] = FFFFF (max 20-bit number)

[ FFFF : FFFF ] = 10FFEF (oh shit, 21-bit number!)

Alors, vous pouvez répondre encore plus de 20 bits. Ce qui se produit? L'adresse « enroule autour », comme l'arithmétique de module (comme une conséquence naturelle du matériel). Ainsi, 0x10FFEF devient 0xFFEF.

Et là vous l'avez! Intel embauché des ingénieurs muets, et nous devons vivre avec.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top