2012-01-29 2 views
3

J'essaie actuellement de comprendre comment l'instruction movw fonctionne sur ARM, pour pouvoir éditer hexadécimal une bibliothèque et changer une valeur qui est en train d'être définie avec cette instruction.comment le bras déplacent-ils la carte d'instructions vers le code machine?

La bibliothèque présente le code comme suit (sortie objdump):

[...] 
29c4: f44f 71f0 mov.w r1, #480 ; 0x1e0 
[...] 

Ce que je suis en train de le faire en d'autres termes, est à comprendre comment est 0x1e0/480 représenté dans « f44f 71f0 ». J'ai lu des choses sur le net, y compris http://blogs.arm.com/software-enablement/251-how-to-load-constants-in-assembly-for-arm-architecture/ et je pense que je comprends comment fonctionne movw et ses limites; mais je ne comprends toujours pas comment la valeur affichée sur l'instruction correspond au code binaire réel. Toute documentation ou insigne que vous pourriez être en mesure de fournir sur le sujet est très appréciée :)

Répondre

2

Pour le bras, les instructions sont décrites dans le (s) manuel (s) de référence ARM ARM, ARM Architectural. Rendez-vous au http://infocenter.arm.com puis, à gauche, trouvez l'architecture puis trouvez l'architecture qui vous intéresse. Il s'agit d'une instruction thumb2, donc vous voulez l'armv7-m.

Cela ressemble à coder T2

11110i00010S11110... 

i et S sont égaux à zéro dans votre instruction. imm3 est bits 12 à 14 et IMM8 est bits 7 - 0.

0 111 0001 11110000 

afin que votre imm3 est 0b111 et IMM8 est 0b11110000

vous regardez les constantes immédiates modifiées dans les instructions du pouce section

i ... imm3 ... abcdefgh où abcdefgh sont les imm8 bits votre i: imm3: a bits, 5 bits sont 0b11111

donc vous regardez dans le tableau et vous obtenez imm8 sur le côté droit décalé à gauche 1

00000000 00000000 00000001 bcdefgh0 
00000000 00000000 00000001 11100000 

qui est 0x000001E0

Arm fait un assez bon travail de documenter leurs instructions, mieux que la plupart.

+0

Un grand merci! Avec votre explication et un peu de lecture sur le Manuel de référence architectural, je l'ai compris et j'ai pu éditer ce dont j'avais besoin :) – user1176415

1

est ici MOV T2 encodage (à partir ARM architecture Manuel de référence)

11110 i 0 0010 S 1111 0 imm3 rd imm8 

d = UInt(Rd); 
setflags = (S == ‘1’); 
(imm32, carry) = ThumbExpandImm_C(i:imm3:imm8, APSR.C); 
if d IN {13,15} then UNPREDICTABLE; 

Parce que votre modèle est

 i  S  imm3 rd imm8 
11110 1 0 0010 0 1111 0 111 0001 11110000 

Vous avez i=1, S=0, imm3=111, imm8=11110000



En cochant ce ThumbExpandImm_C() ne, vous comprendrez comment les valeurs sont devenues 0x1e0

// ThumbExpandImm_C() 
// ================== 
(bits(32), bit) ThumbExpandImm_C(bits(12) imm12, bit carry_in) 
if imm12<11:10> == ‘00’ then 
    case imm12<9:8> of 
     when ‘00’ 
      imm32 = ZeroExtend(imm12<7:0>, 32); 
     when ‘01’ 
      if imm12<7:0> == ‘00000000’ then UNPREDICTABLE; 
      imm32 = ‘00000000’ : imm12<7:0> : ‘00000000’ : imm12<7:0>; 
     when ‘10’ 
      if imm12<7:0> == ‘00000000’ then UNPREDICTABLE; 
      imm32 = imm12<7:0> : ‘00000000’ : imm12<7:0> : ‘00000000’; 
     when ‘11’ 
      if imm12<7:0> == ‘00000000’ then UNPREDICTABLE; 
      imm32 = imm12<7:0> : imm12<7:0> : imm12<7:0> : imm12<7:0>; 
      carry_out = carry_in; 
else 
    unrotated_value = ZeroExtend(‘1’:imm12<6:0>, 32);     <--- a 
    (imm32, carry_out) = ROR_C(unrotated_value, UInt(imm12<11:7>)); <--- b 
return (imm32, carry_out); 



Notre imm12 = i:imm3:imm8 (1:111:11110000) = 1111 1111 0000
Nos valeurs passeront lignes (a) et (b) car les 2 bits les plus élevés [11,10] sont '11'

ZeroExtend ('1': imm1 2 < 6: 0>, 32) signifie que vous devez ajouter "1" à [6..0] bits. Ainsi, la valeur devient 1:1110000 = 11110000 (a)
ROR_C (unrotated_value, uint (imm12 < 11: 7>)) ne tourne à droite par [11: 7] = 11111 = 31 qui est la same as rotate left by 1. (B)

Ainsi, la valeur résultante est 1 1110 0000 (a shifted by b) = 0x1e0

Questions connexes