Question

L'article Wikipedia x86 Assemblée dit que « le registre IP ne peut pas être consulté par le programmeur directement. "

Directement des moyens avec des instructions comme mov et ajouter.

Pourquoi pas? Quelle est la raison derrière cela? Quelles sont les restrictions techniques?

Était-ce utile?

La solution

Vous ne pouvez pas y accéder directement parce qu'il n'y a pas de cas d'utilisation légitime. Avoir un changement d'instruction arbitraire eip rendrait la prédiction de branchement très difficile, et probablement ouvrir toute une série de problèmes de sécurité.

Vous pouvez modifier eip en utilisant jmp, call ou ret. Vous ne pouvez pas lire directement ou écrire à l'aide d'opérations normales eip

Réglage eip à un registre est aussi simple que jmp eax. Vous pouvez également faire push eax; ret, qui pousse la valeur de eax à la pile puis retourne (à savoir pops et sauts). La troisième option est call eax qui fait un appel à l'adresse dans eax.

La lecture peut se faire comme ceci:

call get_eip
  get_eip:
pop eax ; eax now contains the address of this instruction

Autres conseils

Cela aurait été une conception possible pour x86. ARM ne exposer son compteur de programme pour la lecture / écriture comme R15. C'est inhabituel, cependant.

Il permet une fonction très compacte prologue / épilogue, ainsi que la possibilité de pousser ou de plusieurs registres pop avec une seule instruction: push {r5, lr} à l'entrée, et pop {r5, pc} au retour. (Popping la valeur enregistrée du registre de lien dans le compteur de programme).

Cependant, il fait des implémentations haute perf / out-of-order ARM moins pratique, et a été abandonné pour AArch64.


il est possible, mais consomme un des registres . des registres de 32 bits ARM a 16 nombre entier (y compris PC), de sorte qu'un numéro de registre prend 4 bits pour coder en code machine ARM. Un autre registre est presque toujours lié comme le pointeur de la pile, donc ARM a 14 registres entiers à usage général. (LR peut être sauvegardé dans la pile, de sorte qu'il peut être et est utilisé en tant que registre à usage général à l'intérieur des organes de fonction).

La plupart des x86 moderne est héritée de 8086. Il a été conçu à l'instruction de longueur variable assez compact codage, et seulement huit registres, ne nécessitant que trois bits pour chaque registre src et dst dans le code machine.

Dans le 8086, ils ne sont pas très fins générales et SP-adressage relatif est impossible d'origine en mode 16 bits, donc essentiellement 2 registres (SP et BP) sont attachés pour des trucs de la pile. Cela ne laisse que 6 registres à usage un peu général, et d'avoir un d'entre eux soit le PC au lieu d'usage général serait une réduction considérable dans les registres disponibles, ce qui augmente considérablement la quantité de déversement / reload dans le code typique.


AMD64 ajouté r8-r15, et le mode d'adressage RIP-parent. modes lea rsi, [rip+whatever] et RIP-adressage relatif à l'accès direct aux données statiques et constantes, est tout ce dont vous avez besoin pour le code indépendant de la position efficace. Indirects instructions de JMP sont tout à fait suffisant pour l'écriture RIP.

Il n'y a vraiment rien à gagner en permettant des instructions arbitraires à utiliser pour lire ou écrire le PC, puisque vous pouvez toujours faire la même chose avec un registre entier et un saut indirect. Il serait presque inconvénient pur pour x86-64 de R15 être la même chose que RIP, en particulier pour la performace de l'architecture comme cible du compilateur. (Substance asm écrit à la main bizarre était déjà très bien une chose rare de niche en 2000, AMD64 a été conçu.)

AMD64 est vraiment la première fois que x86 pouvait vraisemblablement gagné un compteur de programme entièrement exposé comme ARM, mais il y avait beaucoup de bonnes raisons de ne pas le faire.

Je pense qu'ils voulaient dire que le registre IP ne peut pas être directement accessible de la même manière les autres registres sont accessibles. Les programmeurs peuvent certainement écrire IP, par exemple en émettant une instruction de saut.

jmp établira le registre de EIP.

ce code sera mis eip à 00.401.000:

mov eax, 00401000
jmp eax ;set Eip to 00401000

et pour obtenir EIP

call GetEIP
.
.
GetEIP:
mov eax, [esp]
ret
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top