1

Bonjour,

Afin de connaître le nombre de MIPS disponibles sur mon ARM9, j'ai créé une boucle while en C que j'ai compilé à l'aide de gcc pour en obtenir le code assembleur correspondant. Par la suite, il me sera possible de connaître le nombre de cycle et d'en déduire le nombre de MIPS.

J'ai déjà fait de l'assembleur auparavant mais certaines instructions me sont inconnues.

.L3:
ldr r3, .L5 <== Je ne sais pas exactement ce qu'il charge dans r3
ldr r3, [r3, #0] <== Récupère la valeur de cpt
add r2, r3, #1
ldr r3, .L5
str r2, [r3, #0]
.L2:
ldr r3, .L5
ldr r2, [r3, #0]
ldr r3, .L5+4
cmp r2, r3
bne .L3
ldmfd sp, {r3, fp, sp, pc}
.L6:
.align 2
.L5:
.word cpt
.word 180000000
.size main, .-main
.ident "GCC: (GNU) 4.3.4"
.section .note.GNU-stack,"",%progbits

Ce sont surtout les ldr rx, .L5 qui ne sont pas très explicite.

--
Si vous connaissez un simulateur, debugger, ... pour ARM9, aussi bien sur linux que windows, je suis preneur.

Merci par avance

Newbie

2

un cours sur le fonctionnement de l'architecture arm te serait plus utile.

parce que ldr c'est load, tout simplement. Donc il charge le contenu de la mémoire à l'adresse .L5 dans r3.

et comme .L5 est une adresse dont le contenu est l'adresse de cpt, ben le ldr r3, [r3+0] récupère vraiment le contenu de la variable cptr, sa valeur quoi.

c'est une astuce utilisée car l'arm n'a pas d'instruction pour charger directement le contenu d'une adresse complète dans un registre. Il ne peut charger que des adresses sur 8 bits significatifs je crois. Donc l'astuce c'est de lui faire charger le contenu d'une adresse "pas loin", qui elle contient vraiment l'adresse que tu veux.

en gros, c'est impossible de faire directement ldr r3, cpt, parce que cpt peut être à une adresse que l'instruction ldr peut pas encoder. Donc il faut un intermédiaire.

le débogueur s'appelle gdb, il y a un "target sim" qui permet de simuler l'arm sur pc.

3

squalyl (./2) :
c'est une astuce utilisée car l'arm n'a pas d'instruction pour charger directement le contenu d'une adresse complète dans un registre. Il ne peut charger que des adresses sur 8 bits significatifs je crois. Donc l'astuce c'est de lui faire charger le contenu d'une adresse "pas loin", qui elle contient vraiment l'adresse que tu veux.

Les boules eek

4

Ok merci, c'est ce que je pensais, sans être trop sûr smile

Par la suite, il fait un :
ldr r3, .L5+4
Je pense qu'il récupère directement la valeur du 2e word, mais pourquoi 4? La longeur d'un word c'est bien 2 octets? Il ne devrait pas faire +2?
Pourquoi fait-il ça? et non ldr r3, [r3, #2]?

Merci d'avance
Newbie

5

non un word fait 4 octets car c'est une architecture 32 bits. 16 bits ou 2 octets, c'est pour un short.

Folco: c'est caractéristique de ce qu'on appelle une machine RISC load/store. Les opérations favorisent les registres. Dès que tu touches la mémoire principale, il faut des opérations spéciales.

en fait c'est plus sioux que ça. en ARM les instructions font toutes 32 bits exactement et pas moyen d'utiliser 2 mots de 32 bits comme sur le 68k.

LDR se démerde pour encoder en 32 bits :
- un code de condition
- un bit pour savoir si on doit affecter les flags
- d'autres flags
- deux registres parmi 16
- une constante de 8 bits
- et un shift de cette constante

voir
http://simplemachines.it/doc/arm_inst.pdf#13
http://simplemachines.it/doc/arm_inst.pdf#33

donc 'est vraiment 8 bits significatifs mais les valeurs peuvent être en fait bien plus grandes, style 0x42<<5.

Mais là, le compilo il est emmerdé, cpt est potentiellement un relogement ou les 32 bits peuvent changer, donc paf il peut pas utiliser un simple LDR. par contre si l'offset est connu on peut optimiser.

6

Impec!
Merci pour les réponses!
Je n'ai plus qu'à lire les docs pour pouvoir en déduire le nombre de cycle.
Merci
Newbie

7

Toujours dans la même optique de connaître le nombre de MIPS, j'ai analysé le nombre de CPI (Cycle Par Instruction) et je souhaiterais savoir s'il est juste, je ne prends pas en compte la gestion de la mémoire, qui, je pense, ne joue pas de rôle :

L3:
ldr r3, .L5 => 3 cycles
ldr r3, [r3, #0] => 3
add r2, r3, #1 => 1
ldr r3, .L5 => 3
str r2, [r3, #0] => 1
.L2:
ldr r3, .L5 => 3
ldr r2, [r3, #0] => 3
ldr r3, .L5+4 => 3
cmp r2, r3 => 1
bne .L3 => 3
ldmfd sp, {r3, fp, sp, pc}
.L6:
.align 2
.L5:
.word cpt
.word 180000000
.size main, .-main
.ident "GCC: (GNU) 4.3.4"
.section .note.GNU-stack,"",%progbits

Est-ce correcte?
Merci
Newbie

8

squalyl (./5) :
en fait c'est plus sioux que ça

Normal, pour un bi-endian, il êst de fait encore plus sioux embarrassed

(hem, désolé grin)
avatar

9

trisotfl (moi je préfère les Wendat embarrassed)

10

Folco (./3) :
squalyl (./2) :
c'est une astuce utilisée car l'arm n'a pas d'instruction pour charger directement le contenu d'une adresse complète dans un registre. Il ne peut charger que des adresses sur 8 bits significatifs je crois. Donc l'astuce c'est de lui faire charger le contenu d'une adresse "pas loin", qui elle contient vraiment l'adresse que tu veux.

Les boules eek

C'est logique, comment tu veux encoder le chargement d'une valeur 32 bits dans une instruction 32 bits sinon?
avatar
Highway Runners, mon jeu de racing à la Outrun qu'il est sorti le 14 décembre 2016 ! N'hésitez pas à me soutenir :)

https://itunes.apple.com/us/app/highway-runners/id964932741

11

Je savais pas que l'instruction faisait 32 bits cheeky

12

Ne me dites pas que j'ai tout bon, je ne le croirai pas!
smile
Newbie

13

Folco : pourtant on avait déjà discuté de l'architecture ARM sur IRC et il me semble bien que je t'avais parlé de ça cheeky

EDIT : faut bien séparer deux choses par contre :
- le fait qu'il y ait des instructions dédiées pour accéder à la mémoire, et que toutes les autres instructions ne travaillent qu'avec des registres, c'est typique des processeurs RISC
- le fait qu'on ne puisse pas charger de valeur immédiate de la taille d'un registre (dans ce cas, l'adresse d'un truc que l'on veut lire, mais ça peut être n'importe quoi), c'est spécifique aux ARM. Les autres processeurs RISC que je connais utilisent une instruction plus longue que la normale pour éviter le problème.
avatar
Zeroblog

« Tout homme porte sur l'épaule gauche un singe et, sur l'épaule droite, un perroquet. » — Jean Cocteau
« Moi je cherche plus de logique non plus. C'est surement pour cela que j'apprécie les Ataris, ils sont aussi logiques que moi ! » — GT Turbo

14

Oui, j'avais oublié, mais ça me revient, le coup des entiers 32 bits toussa hehe

15

et le PIC qui a fait une belle entorse au RISC avec son MOVFF sad

crosser: ça j'en sais rien, t'as juste à lire la spec kivabien, c'est infaillible. en plus ça doit dépendre des versions non?

16

squalyl, c'était plus pour vérifier que je ne me suis pas trompé, car la doc kivabien, je pense l'avoir.
La majorité des instructions est réalisée en un cycle, par contre quand on attaque la mémoire c'est plus long!
En tout cas, merci.
Newbie

17

Zerosquare (./13) :
- le fait qu'on ne puisse pas charger de valeur immédiate de la taille d'un registre (dans ce cas, l'adresse d'un truc que l'on veut lire, mais ça peut être n'importe quoi), c'est spécifique aux ARM. Les autres processeurs RISC que je connais utilisent une instruction plus longue que la normale pour éviter le problème.

Heu non sauf erreur en MIPS non plus. Si tu veux charger $12345678 tu écris un truc du genre:
lui $t0, 0x1234
addi $t0, $t0, 0x5678

2 instructions mais toujours plus rapide ou équivalent à une indirection ou au placement d'une constante 32 bits dans un pool ^^
avatar
Highway Runners, mon jeu de racing à la Outrun qu'il est sorti le 14 décembre 2016 ! N'hésitez pas à me soutenir :)

https://itunes.apple.com/us/app/highway-runners/id964932741

18

Je te crois sur parole, j'avais justement un doute sur le MIPS (j'ai jamais touché à cette bête-là).
avatar
Zeroblog

« Tout homme porte sur l'épaule gauche un singe et, sur l'épaule droite, un perroquet. » — Jean Cocteau
« Moi je cherche plus de logique non plus. C'est surement pour cela que j'apprécie les Ataris, ils sont aussi logiques que moi ! » — GT Turbo