Pourquoi utiliser LDR sur MOV (ou vice versa) dans L'assemblage de bras?

je regarde à travers ce tutoriel:http://www.cl.cam.ac.uk/freshers/raspberrypi/tutorials/os/ok01.html

la première ligne d'assemblage est:

ldr r0,=0x20200000

la seconde est:

mov r1,#1

j'ai pensé ldr était pour charger des valeurs de mémoire dans des registres. Mais il semble que le = signifie que le 0x20200000 est une valeur qui n'est pas une adresse mémoire. Les deux lignes semblent charger les valeurs absolues.

20
demandé sur piperchester 2012-12-27 01:50:20

3 réponses

C'est un truc/raccourci. disons, par exemple,

ldr r0,=main

ce qui se produirait est que l'assembleur attribuerait un mot de données, près de l'instruction mais en dehors du chemin d'instruction

ldr r0,main_addr
...
b somewhere
main_addr: .data main

maintenant, étendez cette astuce aux constantes / immédiates, surtout celles qui ne peuvent pas s'insérer dans un mouvement instruction immédiate:

top:
add r1,r2,r3
ldr r0,=0x12345678
eor r1,r2,r3
eor r1,r2,r3
b top

assembler puis démonter

00000000 <top>:
   0:   e0821003    add r1, r2, r3
   4:   e59f0008    ldr r0, [pc, #8]    ; 14 <top+0x14>
   8:   e0221003    eor r1, r2, r3
   c:   e0221003    eor r1, r2, r3
  10:   eafffffa    b   0 <top>
  14:   12345678    eorsne  r5, r4, #125829120  ; 0x7800000

et vous voyez l'assembleur a ajouté le mot de données pour vous et a changé le ldr en un pc par rapport pour vous.

maintenant, si vous utilisez un immédiat qui s'inscrit dans une instruction mov, alors peut-être en fonction de l'assembleur, certainement avec le gnu que j'utilise, il l'a transformé en mov pour moi

top:
add r1,r2,r3
ldr r0,=0x12345678
ldr r5,=1
mov r6,#1
eor r1,r2,r3
eor r1,r2,r3
b top


00000000 <top>:
   0:   e0821003    add r1, r2, r3
   4:   e59f0010    ldr r0, [pc, #16]   ; 1c <top+0x1c>
   8:   e3a05001    mov r5, #1
   c:   e3a06001    mov r6, #1
  10:   e0221003    eor r1, r2, r3
  14:   e0221003    eor r1, r2, r3
  18:   eafffff8    b   0 <top>
  1c:   12345678    eorsne  r5, r4, #125829120  ; 0x7800000

donc c'est essentiellement un raccourci dactylographique, comprenez que vous donnez au monteur le pouvoir de trouver un endroit pour coller la constante, ce qu'il fait habituellement un bon travail, se plaint parfois, pas sûr si je l'ai vu ne pas le faire en toute sécurité. Parfois, vous avez besoin d'un .ltorg ou .mettre en commun dans le code pour encourager le monteur à trouver une place.

17
répondu old_timer 2012-12-26 22:04:50

une réponse plus courte, juste de la part de quelqu'un qui est plus près de votre niveau, espérons que cela vous aidera: dans ARM, les instructions ont 32 bits. Certains bits sont utilisés pour identifier l'opération, les uns pour les opérandes, et, dans le cas de l'instruction MOV, certains sont disponibles pour une valeur immédiate (#1, par exemple).

Comme vous pouvez le voir ici (page 33), Il n'y a que 12 bits disponibles pour la valeur immédiate. Au lieu d'utiliser chaque bit comme le nombre (qui varie de 0 à 2 ^ 12-1~4095), l'instruction calcule le nombre immédiat en tournant à droite (ROR) les 8 premiers bits par deux fois la quantité spécifiée dans les 4 derniers bits. C'est-à -immediate = first 8 bits ROR 2*(last four bits).

de cette façon, nous pouvons obtenir beaucoup plus de nombres que seulement 4096 (voir page 34 pour un bref résumé des immédiats possibles).

juste au cas où notre nombre ne peut pas être converti en une instruction comme la précédente (257 ne peut pas être exprimé comme 8 bits tournant deux fois n'importe quel 4 bits), alors, nous devons utiliser LDR r0, = 257

dans ce cas, le compilateur sauvegarde le numéro 257 en mémoire, proche du code du programme, de sorte qu'il peut être adressé par rapport au PC, et le charge de mémoire, comme dwelch l'a expliqué en détail.

Remarque: Si vous suivez ce tutoriel, puis lorsque vous essayez de "faire" avec mov r0, #257, vous obtiendrez une erreur, et vous devez essayer manuellement ldr r0, =257.

6
répondu Fernando 2013-07-10 14:31:42

ldr = Charge De Vous Inscrire

mov = MOVe

les deux font effectivement la même chose, mais de façons différentes.

la différence ressemble beaucoup à la différence entre

#define CONST 5

et

int CONST = 5;

en langage C.

mov est vraiment rapide car il a la valeur d'accompagnement directement stocké dans le cadre de l'instruction (dans le format de 12 bits décrit dans la réponse ci-dessus). Il a quelques limites dues à la façon dont il stocke la valeur. Pourquoi? Parce que

  • 12 bits n'est pas suffisant pour stocker des nombres énormes comme les adresses mémoire 32 bits.
  • 8 premiers bits ROR 2 * (Les 4 derniers bits) ne peut pas représenter n'importe quel nombre, même dans la gamme de 12 bits.

ldr, d'autre part, est polyvalent (principalement en raison de l'optimisation des compilateurs). Cela fonctionne comme ceci (comme le montre la routine désassemblée)

  • si la valeur peut être représentée en 12-bit & premiers 8 bits ROR 2 * (Les 4 derniers bits) alors le compilateur le change en un mov instructions accompagnant la valeur.

  • sinon, la valeur est conservée comme une donnée, chargée en RAM, à un endroit. Et il est chargé dans le Registre requis en accédant à partir de mémoire utilisant l'offset du compteur de programmes.

j'espère que cela a aidé.

1
répondu Suhel Chakraborty 2017-03-18 17:04:25