private void WriteShift(ArmInstructionOperand op, MachineInstructionWriter writer) { switch (op.Shifter.Type) { case ArmShifterType.ASR: WriteImmShift("asr", op.Shifter.Value, writer); break; case ArmShifterType.LSL: WriteImmShift("lsl", op.Shifter.Value, writer); break; case ArmShifterType.LSR: WriteImmShift("lsr", op.Shifter.Value, writer); break; case ArmShifterType.ROR: WriteImmShift("ror", op.Shifter.Value, writer); break; case ArmShifterType.RRX: writer.Write(",rrx"); break; case ArmShifterType.ASR_REG: WriteRegShift("asr", op.Shifter.Value, writer); break; case ArmShifterType.LSL_REG: WriteRegShift("lsl", op.Shifter.Value, writer); break; case ArmShifterType.LSR_REG: WriteRegShift("lsr", op.Shifter.Value, writer); break; case ArmShifterType.ROR_REG: WriteRegShift("ror", op.Shifter.Value, writer); break; case ArmShifterType.RRX_REG: WriteRegShift("rrx", op.Shifter.Value, writer); break; case ArmShifterType.Invalid: break; } }
public void Write(ArmInstructionOperand op, MachineInstructionWriter writer) { switch (op.Type) { case ArmInstructionOperandType.Immediate: if (instruction.Id == Opcode.B || instruction.Id == Opcode.BL || instruction.Id == Opcode.BLX) { writer.Write("$"); writer.WriteAddress( string.Format("{0:X8}", op.ImmediateValue.Value), Address.Ptr32((uint)op.ImmediateValue.Value)); break; } writer.Write("#"); WriteImmediateValue(op.ImmediateValue.Value, writer); break; case ArmInstructionOperandType.CImmediate: writer.Write("c{0}", op.ImmediateValue); break; case ArmInstructionOperandType.PImmediate: writer.Write("p{0}", op.ImmediateValue); break; case ArmInstructionOperandType.Register: if (op.IsSubtracted) writer.Write('-'); writer.Write(A32Registers.RegisterByCapstoneID[op.RegisterValue.Value].Name); WriteShift(op, writer); break; case ArmInstructionOperandType.Memory: WriteMemoryOperand(op, writer); break; case ArmInstructionOperandType.SetEnd: writer.Write(op.SetEndValue.ToString().ToLowerInvariant()); break; default: throw new NotImplementedException(string.Format( "Can't disasseble {0} {1}. Unknown operand type: {2}", instruction.Mnemonic, instruction.Operand, op.Type)); } }
private void WriteMemoryOperand(ArmInstructionOperand op, MachineInstructionWriter writer) { writer.Write('['); writer.Write(A32Registers.RegisterByCapstoneID[op.MemoryValue.BaseRegister].Name); int displacement = op.MemoryValue.Displacement; if (displacement != 0) { if (true) // preincInternal.ArchitectureDetail) { writer.Write(","); if (displacement < 0) { displacement = -displacement; writer.Write("-"); } writer.Write("#"); WriteImmediateValue(displacement, writer); writer.Write("]"); if (instruction.ArchitectureDetail.WriteBack) writer.Write("!"); } else { writer.Write("],"); if (displacement < 0) { displacement = -displacement; writer.Write("-"); } WriteImmediateValue(displacement, writer); } } else { if (op.MemoryValue.IndexRegister != ArmRegister.Invalid) { writer.Write(","); // NOTE: capstone.NET seems to reverse the sense of this scale parameter. if (op.IsSubtracted) writer.Write("-"); writer.Write(A32Registers.RegisterByCapstoneID[op.MemoryValue.IndexRegister].Name); } if (op.Shifter.Type != ArmShifterType.Invalid) { WriteShift(op, writer); } writer.Write(']'); if (instruction.ArchitectureDetail.WriteBack && IsLastOperand(op)) writer.Write("!"); } }
/// <summary> /// Returns true if <paramref name="op"/> is the last operand of the instruction. /// </summary> /// <param name="op"></param> /// <returns></returns> public bool IsLastOperand(ArmInstructionOperand op) { var ops = instruction.ArchitectureDetail.Operands; return op == ops[ops.Length-1]; }