diff --git a/libr/asm/arch/arm/armass.c b/libr/asm/arch/arm/armass.c index 512c0ceb53..34301c225b 100644 --- a/libr/asm/arch/arm/armass.c +++ b/libr/asm/arch/arm/armass.c @@ -76,7 +76,13 @@ static ArmOp ops[] = { { "ldrex", 0x9f0f9000, TYPE_MEM }, { "ldr", 0x9000, TYPE_MEM }, + { "strexh", 0x900fe000, TYPE_MEM }, + { "strexb", 0x900fc000, TYPE_MEM }, { "strex", 0x900f8000, TYPE_MEM }, + { "strbt", 0x0000e0e4, TYPE_MEM }, + { "strb", 0x0000c0e5, TYPE_MEM }, + { "strd", 0xf000c0e1, TYPE_MEM }, + { "strh", 0xb00080e1, TYPE_MEM }, { "str", 0x8000, TYPE_MEM }, { "blx", 0x30ff2fe1, TYPE_BRR }, @@ -908,7 +914,7 @@ static int arm_assemble(ArmOpcode *ao, ut64 off, const char *str) { if (ao->a[0] || ops[i].type == TYPE_BKP) switch (ops[i].type) { case TYPE_MEM: - if (!strcmp (ops[i].name + 2, "rex")) { + if (!strncmp (ops[i].name, "strex", 5)) { rex = 1; } getrange (ao->a[0]); @@ -922,8 +928,40 @@ static int arm_assemble(ArmOpcode *ao, ut64 off, const char *str) { if ( (r0 < 0 || r0 > 15) || (r1 > 15 || r1 < 0) ) { return 0; } - ao->o |= r0 << 20; - if (!strcmp (ops[i].name, "strex")) { + ao->o |= r0 << 20; + if (!strcmp (ops[i].name, "strd")) { + r1 = getreg (ao->a[2]); + if (r1 == -1) { + break; + } + ao->o |= r1 << 8; + if (ao->a[3]) { + char *bracket = strchr (ao->a[3], ']'); + if (bracket) { + *bracket = '\0'; + } + int num = getnum (ao->a[3]); + ao->o |= (num & 0x0f) << 24; + ao->o |= ((num >> 4) & 0x0f) << 16; + } + break; + } + if (!strcmp (ops[i].name, "strh")) { + ao->o |= r1 << 8; + if (ao->a[2]) { + reg = getreg (ao->a[2]); + if (reg != -1) { + ao->o |= reg << 24; + } else { + ao->o |= 1 << 14; + ao->o |= getnum (ao->a[2]) << 24; + } + } else { + ao->o |= 1 << 14; + } + break; + } + if (rex) { ao->o |= r1 << 24; } else { ao->o |= r1 << 8; // delta @@ -936,12 +974,9 @@ static int arm_assemble(ArmOpcode *ao, ut64 off, const char *str) { if (ret != -1) { if (rex) { ao->o |= 1; - } else { - ao->o |= (strstr (str,"],")) ? 6 : 7; - } - if (!strcmp (ops[i].name, "strex")) { ao->o |= (ret & 0x0f) << 8; } else { + ao->o |= (strstr (str,"],")) ? 6 : 7; ao->o |= (ret & 0x0f) << 24; } if (ao->a[3]) { @@ -953,6 +988,9 @@ static int arm_assemble(ArmOpcode *ao, ut64 off, const char *str) { } } else { int num = getnum (ao->a[2]) & 0xfff; + if (err) { + break; + } if (rex) { ao->o |= 1; } else {