diff options
Diffstat (limited to 'src/arch/operand.c')
-rw-r--r-- | src/arch/operand.c | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/src/arch/operand.c b/src/arch/operand.c index 33807bc..e24a3e0 100644 --- a/src/arch/operand.c +++ b/src/arch/operand.c @@ -156,6 +156,85 @@ bool fill_imm_operand(asm_operand *operand, AsmOperandSize size, const uint8_t * /****************************************************************************** * * +* Paramètres : operand = structure dont le contenu est à définir. * +* size = taille de l'opérande souhaitée. * +* data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* ref = adresse de référence. * +* * +* Description : Crée une opérande contenant une valeur relative sur x bits. * +* * +* Retour : true si l'opération s'est effectuée avec succès, false sinon.* +* * +* Remarques : - * +* * +******************************************************************************/ + +bool fill_relimm_operand(asm_operand *operand, AsmOperandSize size, const uint8_t *data, off_t *pos, off_t len, uint64_t ref) +{ + bool result; /* Bilan à retourner */ + off_t old_pos; /* Sauvegarde de l'évolution */ + int8_t val8; /* Valeur sur 8 bits */ + int16_t val16; /* Valeur sur 16 bits */ + uint32_t val32; /* Valeur sur 32 bits */ + int64_t val64; /* Valeur sur 64 bits */ + + old_pos = *pos; + result = fill_imm_operand(operand, size, data, pos, len); + + if (result) + switch (size) + { + case AOS_8_BITS: + if (operand->value.val8 & 0x80) + { + val8 = operand->value.val8 - 1; + val8 = ~val8; + operand->value.val8 = ref + (*pos - old_pos); + operand->value.val8 -= val8; + } + else operand->value.val8 += ref + (*pos - old_pos); + break; + case AOS_16_BITS: + if (operand->value.val16 & 0x8000) + { + val16 = operand->value.val16 - 1; + val16 = ~val16; + operand->value.val16 = ref + (*pos - old_pos); + operand->value.val16 -= val16; + } + else operand->value.val16 += ref + (*pos - old_pos); + break; + case AOS_32_BITS: + if (operand->value.val32 & 0x80000000) + { + val32 = operand->value.val32 - 1; + val32 = ~val32; + operand->value.val32 = ref + (*pos - old_pos); + operand->value.val32 -= val32; + } + else operand->value.val32 += ref + (*pos - old_pos); + break; + case AOS_64_BITS: + if (operand->value.val64 & 0x8000000000000000ull) + { + val64 = operand->value.val64 - 1; + val64 = ~val64; + operand->value.val64 = ref + (*pos - old_pos); + operand->value.val64 -= val64; + } + else operand->value.val64 += ref + (*pos - old_pos); + break; + } + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : operand = instruction à traiter. * * buffer = tampon de sortie mis à disposition. [OUT] * * len = taille de ce tampon. * |