ASSEMBLER_ARM - Kasimashi/Systemes-embarques GitHub Wiki
Le Language Assembleur (ARM)
ARM Instruction set encoding/decoding
Le code est encodé suivant deux références : ARM Instruction & Thumb. Pour décoder le code il suffit de se référencer au manuel de ARM :
Pour comprendre on peux essayer d'encoder l'instruction ORRS r3, r1, r0, LSL #2
: le résultat donne 0xEA510380
Pour écrire un programme qui fait C = A + B on va écrire le programme suivant :
LD R3, [&A] // On charge depuis la mémoire la valeur stocké dans l'adresse &A dans le registre R3 (choisi aléatoirement)
LD R2, [&B] // On charge depuis la mémoire la valeur stocké dans l'adresse &B dans le registre R2 (choisi aléatoirement)
ADD R0,R3,R2 // On effectue l'addition et on stocke le résultat dans R0
STR R0, [&C] // On met la valeur du résultat en mémoire à l'adresse &C
Chacune de ces instructions ont un encodage binaire que le processeur est capable de comprendre grâce au jeu d'instruction.
Assembly directive
Instruction | |
---|---|
AREA | Créer un nouveau block de donnée ou de code |
ENTRY | Permet de déclarer un point d'entrée pour le programme |
ALIGN | Aligne les donnée ou le code à un 'memory boundary' |
DCB (Define Constant Byte) | Alloue un ou plusieurs bytes (8 bits) de données |
DCW (Define Constant Half-word) | Alloue un ou plusieurs halfword (16 bits) de données |
DCD (Define Constant Word) | Alloue un ou plusieurs word (32 bits) de données |
DCQ (Define Constant Double Word) | Alloue un ou plusieurs double word (64 bits) de données |
DCFS | Alloue un ou plusieurs single precision (32 bits) floating point numbers |
DCFB | Alloue un ou plusieurs double precision (64 bits) floating point numbers |
SPACE (Define 0 bytes) | Alloue un espace mémoire remplis de 0 |
FILL (Define initialized bytes) | Alloue un block de mémoire remplis avec une valeur donnée |
EQU | Donne un nom de symbole à une constante numérique |
RN | Donne un nom de symbole à un registre |
EXPORT | Déclare un symbole et le rend visible par les autres fichiers sources |
IMPORT | Récupère un symbole déclaré dans un autre fichier source |
INCLUDE/GET | Inclus un fichier source externe du fichier courant |
PROC | Déclare un début de procédure ou de fonction |
ENDP | Déclare la fin d'une procédure ou d'une fonction |
END | Déclare la fin d'un fichier source |
Exemple :
AREA myData, DATA, READWRITE
hello DCB "HelloWorld!",0 ; Allocation d'une chaine de caractère avec un caractère de fin de ligne
dollar DCB 2,10,0,200 ; Allocation d'entier allant de -128 à 255.
score DCD 2,3.5
miles DCW 100,200,50
p SPACE 255
f FILL 20,0xFF,1 ; Allocation de 20 bytes setté à 0xFF
binary DCB 2_01010101 ; Allocation d'un byte en binaire
octal DCB 8_73 ;Allocation d'un byte en octal
char DCB 'A' ;Allocation d'un byte en ASCII
Arithmetic Instructions
Voici une liste des opérations arithmétiques avec des résultats sur 32 bits.
Instruction | Informations |
---|---|
ADD {Rd,} Rn, Op2 | Add Rd <- Rn + Op2 |
ADC {Rd,} Rn, Op2 | Add with carry. Rd <- Rn + Op2 + Carry |
SUB {Rd,} Rn, Op2 | Substract. Rd <- Rn - Op2 |
SBC {Rd,} Rn, Op2 | Substract with carry. Rd <- Rn - Op2 + Carry - 1 |
RSB{Rd,} Rn, Op2 | Reverse substract Rd <- Op2 - Rn |
MUL {Rd,} Rn, Rm | Multiply; Rd <- (Rn * Rm) [31:0] |
MLA Rd, Rn, Rm, Ra | Multiply with accumulate Rd<- (Ra + (Rn*Rm))[31:0] |
MLS Rd, Rn, Rm, Ra | Multiply and substract. Rd <- (Ra - (Rn*Rm))[31:0] |
SDIV {Rd,} Rn, Rm | Signed divide Rd<- Rn/Rm |
UDIV {Rd,} Rn, Rm | Unsigned divided Rd <- Rn/Rm |
SSAT Rd, #n, Rm{,shift,#s} | Signed saturate |
USAT Rd, #n, Rm{,shift,#s} | Unsigned saturate |
Comparaison
Instruction | Informations | Action |
---|---|---|
CMP Rn, Op2 | Compare | Set NZCV flags on Rn - Op = 0 |
CMN Rn, Op2 | Compare Negative | Set NZCV flags on Rn - Op = 0 |
TST Rn, Op2 | Test | Set NZCV flags on Rn AND Op2 == TRUE |
TEQ Rn, Op2 | Test Equivalence | Set NZCV flags on Rn EOR Op2 == TRUE |
Bitwise Logic Operation
Instruction | Informations |
---|---|
AND {Rd,} Rn, Op2 | Bitwise logic AND. Rd <- Rn & Op2 |
ORR {Rd,} Rn, Op2 | Bitwise logic OR Rd <- Rn |
EOR {Rd,} Rn, Op2 | Bitwise logic exclusive OR . Rd <- Rn ^ Op2 |
ORN {Rd,} Rn, Op2 | Bitwise logic NOT OR. Rd <- Rn & (not Op2) |
BIC {Rd,} Rn, Op2 | Bit clear. Rd <- Rn & NOT Op2 |
BFC Rd, #lsb, #width | Bit field clear. Rd[(width+lsb-1):lsb] <- 0 |
BFI Rd, Rn, #lsb, #width | Bit field insert. Rd[(width+lsb-1):lsb] <- Rn[width-1):0] |
MVN Rd, Op2 | Logically negate all bits Rd <- 0xFFFFFFFF EOR Op2 |
Data Movement
Instruction | Informations |
---|---|
MOV Rd, Op2 | Rd <- Op2 |
MVN Rd, Op2 | Rd <- NOT(Op2) |
MRS Rd, spec_reg | Move from special register to general register |
MSR spect_reg, Rm | Move from general register to special register |
Conditional Instruction
Outre l'instruction de comparaison de données (CMP, CMN, TEQ, TST), la plupart des instructions peuvent mettre à jour l'indicateur d'état du programme (N, Z, C et V). si le suffixe S est ajouté.
L'une des principales caractéristiques du langage d'assemblage ARM est qu'une instruction peut être exécutée de manière optionnelle en fonction des indicateurs d'état du programme.
Cette fonctionnalité n'est souvent pas disponible dans d'autres langages d'assemblage.
Nous prenons l'instruction add
comme exemple pour illustrer l'exécution conditionnelle. Par défaut, l'instruction add r3, r2,r1
est toujours exécutée quelle que soit la valeur du drapeau d'état du programme. Le drapeau conditionnel, tel que EQ peut être ajouté à ADD pour former une instruction exécutée conditionnellement ADDEQ comme indiqué dans le tableau ci-dessous
Instruction | Condition | Flag testé |
---|---|---|
ADDEQ r3,r2,r1 | Add if EQual | Add if Z = 1 |
ADDNE r3,r2,r1 | Add if Not EQual | Add if Z = 0 |
ADDHS r3,r2,r1 | Add if Unsigned Higher or Same | Add if C = 1 |
ADDLO r3,r2,r1 | Add if Unsigned LOwer | Add if C = 0 |
ADDMI r3,r2,r1 | Add if Minus(Negative) | Add if N = 1 |
ADDPL r3,r2,r1 | Add if PLus (Positive or Zero) | Add if N = 0 |
ADDVS r3,r2,r1 | Add if oVerflow Set | Add if V = 1 |
ADDVC r3,r2,r1 | Add if oVerflow Clear | Add if V = 0 |
ADDHI r3,r2,r1 | Add if Unsigned HIgher | Add if C = 1 & Z = 0 |
ADDLS r3,r2,r1 | Add if Unsigned Lower or Same | Add if C = 0 & Z = 1 |
ADDGE r3,r2,r1 | Add if Signed Greater or Equal | N = V |
ADDLT r3,r2,r1 | Add if Signed Less than | N!=V |
ADDGT r3,r2,r1 | Add if Signed Greater Then | Add if Z = 0 & N = V |
ADDLE r3,r2,r1 | Add if Signed Less than or Equal | Add if Z = 1 or N != V |
Branch Instruction
Les instructions qui permettent de faire des sauts dans le code :
Instruction | Description | Flag testé | |
---|---|---|---|
Unconditional Branch | B label | Branch to label | none |
Conditional Branch | BEQ label | Branch if EQual | Z=1 |
Conditional Branch | BNE label | Branch if Not Equal | Z=0 |
Conditional Branch | BCS/BHS label | Branch unsigned Higher or Same | C=1 |
Conditional Branch | BCC/BLO label | Branch if unsigned LOwer | C=0 |
Conditional Branch | BMI label | Branch if MInus (Negative) | N=1 |
Conditional Branch | BPL label | Branch if PLus (Positive or zero) | N=0 |
Conditional Branch | BVS label | Branch if oVerflow Set | V=1 |
Conditional Branch | BVC label | Branch if oVerflow Clear | V=0 |
Conditional Branch | BHI label | Branch if unsinged HIgher | C = 1 & Z = 0 |
Conditional Branch | BLS label | Branch if unsigned Lover or Same | C = 0 & Z = 1 |
Conditional Branch | BGE label | Branch if Greater or Equal | N = V |
Conditional Branch | BLT label | Branch if signed Less Than | N != V |
Conditional Branch | BGT label | Branch if signed Greater Than | Z = 0 & N = V |
Conditional Branch | BLE label | Branch is signed Less than or Equal | Z = 1 & N != V |