1 #include "arm_thumb.h" 2 #include "arm_common.h" 3 4 namespace REDasm { 5 ARMThumbAssembler()6ARMThumbAssembler::ARMThumbAssembler(): ARMCommonAssembler<CS_ARCH_ARM, CS_MODE_THUMB>() { } 7 pc(const InstructionPtr & instruction) const8u64 ARMThumbAssembler::pc(const InstructionPtr &instruction) const 9 { 10 /* 11 * https://stackoverflow.com/questions/24091566/why-does-the-arm-pc-register-point-to-the-instruction-after-the-next-one-to-be-e 12 * 13 * In Thumb state: 14 * - For B, BL, CBNZ, and CBZ instructions, the value of the PC is the address 15 * of the current instruction plus 4 bytes. 16 * 17 * - For all other instructions that use labels, the value of the PC is the address 18 * of the current instruction plus 4 bytes, with bit[1] of the result cleared 19 * to 0 to make it word-aligned. 20 */ 21 22 switch(instruction->id) 23 { 24 case ARM_INS_B: 25 case ARM_INS_BL: 26 case ARM_INS_CBNZ: 27 case ARM_INS_CBZ: 28 return instruction->address + 4; 29 30 default: 31 break; 32 } 33 34 return (instruction->address + 4) & 0xFFFFFFFE; 35 } 36 37 } // namespace REDasm 38