2010-08-16 25 views
1

avertissement: Je suis un nouveau venu ASM. Je dois sans doute revoir mes 2s compléter ou quelque chose pour bien comprendre :(décalage gauche et puis immédiatement passer à droite dans ASM?

Je suis confus quant à l'objet de ce qui suit:?

.... 
BL some_func 
MOV R3, R0,LSL#16 
MOVS R3, R3,LSR#16 
.... 

pourquoi le déplacement arrière et les movs

+0

http://net.pku.edu.cn/~course/cs201/2003/mirrorWebster.cs.ucr.edu/Page_asm/ArtofAssembly/ch15/CH15-2.html#HEADING2-1 – Borealid

+0

Quel processeur, ARM ? – starblue

+0

@borealid - merci, je suis à la recherche de didacticiels réels sur asm @starblue c'est le bras –

Répondre

2

Dans le décalage à gauche, les bits débordés seront perdus. Donc, tous les bits ci-dessus 32-16 = 16 chiffres sera remis à zéro après déplacement vers la droite.

 r0 =     aaaabbbbccccdddd eeeeffffgggghhhh 
lsl, 16 -> aaaabbbbccccdddd eeeeffffgggghhhh 0000000000000000 
      (overflowed) 
     ->     eeeeffffgggghhhh 0000000000000000 
lsr, 16 ->         eeeeffffgggghhhh 

l'instruction est équivalente à

r3 = r0 & 0xffff; 
+0

qui répond le plus souvent à ma question ...au moins celui que j'ai demandé;) Un morceau de données que j'ai omis était que r0 est une petite valeur à ce point donc je ne vois pas ce qui est gagné ... ive mis à jour la question –

+0

nevermind ... café ne fonctionne pas encore ... je l'obtiens :) –

3

il faut trois instructions pour faire une r0 & = 0xFFFF

 
mov r3,#0x00FF 
orr r3,r3,#0xFF00 
and r0,r0,r3 

Ainsi, le changement et-vient est plus efficace. Ce que vous avez peut-être fait est lié à une variable de 16 bits. Pour être précis, le compilateur doit tronquer les bits supérieurs pour que le programme fonctionne correctement. Si vous aviez utilisé int ou quelque chose il n'a peut-être pas fait cela, pas sûr si c'est comme cela que vous avez instigué ces instructions.

Parfois, vous verrez ceci pour faire une extension de signe mais ce n'était pas un changement arithmétique c'était un changement logique (les zéros arrivant pas le bit de carry).

Peut-être que votre code a fait quelque chose comme si (bonjour & 0xFFFF) alors.

ARM ne met pas à jour les drapeaux normalement à moins que vous lui dites, pour des raisons de performance si rien du code autre comme celui-ci

 
if(a&0xFF) b=0x12; else b=0x34; 
would be something like: 
ands r0,r0,#0xFF 
movne r1,#0x12 
moveq r1,#0x34 

avec d'autres processeurs le et serait toujours mis les drapeaux et l'instruction suivante serait branche provoquant une chasse d'eau.

 
ands r0,r0,#0xFF 
bne notequal 
mov r1,#0x12 
b wasequal 
notequal: 
mov r1,#0x34 
wasequal: 

Beaucoup plus brutal lors de l'exécution. Beaucoup de processeurs écraseraient les drapeaux avec le mouvement immédiat aussi, ce que le bras ne fait pas. (Le mode pouce est une autre histoire). Au lieu de seulement les branches ayant un champ conditionnel, chaque instruction sur le bras a un champ conditionnel, branche s'il est égal, et si égal, ajoutez si égal, sub si égal, branchez si carry set, et si carry set, etc. De même, les instructions qui peuvent modifier les drapeaux ont un bit opcode qui active ou désactive la mise à jour des drapeaux. Vous ajoutez les s à l'instruction. et r0, r1, r2 ne le fait pas mais ands r0, r1, r2 met à jour les drapeaux. Donc, vos deux instructions ont fait deux choses: mettre à zéro les 16 bits supérieurs d'un registre, puis définir les drapeaux pour tout ce qui a suivi. Pour un mov qui était probablement une branche si égal ou branche sinon égal. À quoi ressemblait votre code source original?

+0

merci pour la réponse détaillée ... im essayant toujours de tout grok ... je n'ai pas écrit le code original, c'est le résultat d'un démontage –