Example #1
0
 internal BFFile(BFCodeLabel[] procedures, BFCodeLabel[] jumpLabels, List<BFOpcode> opcodes, BMDFile messageFile = null)
 {
     _procedures = procedures;
     _jumpLabels = jumpLabels;
     _opcodes = opcodes;
     _messageFile = messageFile;
 }
Example #2
0
        private static BFCodeLabel ParseASMLabel(int lineIndex, string nameToken, int jumpIndex, int opIndex, params char[] splitChars)
        {
            BFCodeLabel label = new BFCodeLabel()
            {
                Name = nameToken.Split(splitChars, StringSplitOptions.RemoveEmptyEntries)[0],
                ID = jumpIndex,
                OpcodeIndex = opIndex
            };

            if (label.Name.Length == 0)
                throw new BFASMParserException("Label", lineIndex + 1);

            return label;
        }
Example #3
0
 private static void ReadCodeLabels(BinaryReader reader, ref BFCodeLabel[] array, int count, out bool requireSort)
 {
     array = new BFCodeLabel[count];
     requireSort = false;
     int lastIdx = -1;
     for (int j = 0; j < array.Length; j++)
     {
         array[j] = new BFCodeLabel(reader);
         if (!requireSort && lastIdx > array[j].OpcodeIndex)
             requireSort = true;
         else
             lastIdx = array[j].OpcodeIndex;
     }
 }
Example #4
0
        public static void Disassemble(string path, List<BFOpcode> opcodes, BFCodeLabel[] procedures, BFCodeLabel[] jumpLabels)
        {
            using (StreamWriter writer = new StreamWriter(File.Create(path)))
            {
                int procIdx = 0;
                int jumpIdx = 0;

                // sorting these is faster than searching every interation
                BFCodeLabel[] sortedProcedures = procedures.OrderBy(i => i.OpcodeIndex).ToArray(); 
                BFCodeLabel[] sortedJumpLabels = jumpLabels.OrderBy(i => i.OpcodeIndex).ToArray();

                for (int i = 0; i < opcodes.Count; i++)
                {
                    BFOpcode op = opcodes[i];
                    BFCodeLabel procedure = null;
                    BFCodeLabel jumpLabel = null;

                    // first check if maybe a procedure starts at this index
                    if (procIdx != sortedProcedures.Length && sortedProcedures[procIdx].OpcodeIndex == i)
                    {
                        procedure = sortedProcedures[procIdx++];
                        writer.WriteLine("\n" + procedure.Name + ": \t; start of procedure \"{0}\"", procedure.Name);
                    }
                    // if it's not the start of a procedure then check if it's maybe a jump label
                    else if (jumpIdx != sortedJumpLabels.Length && sortedJumpLabels[jumpIdx].OpcodeIndex == i)
                    {
                        jumpLabel = sortedJumpLabels[jumpIdx++];
                        writer.WriteLine("\n@" + jumpLabel.Name + ": \t; jump label \"{0}\"", jumpLabel.Name);
                    }

                    bool isKnown = BFInstructionToASMKeyword.ContainsKey(op.Instruction);
                    string opStr = isKnown ?
                        BFInstructionToASMKeyword[op.Instruction] :
                        "unk_" + op.Instruction.ToString("X");

                    switch (op.Instruction)
                    {
                        case BFInstruction.CallNative:
                            BFCallNativeType callType = (BFCallNativeType)op.Operand.ImmediateValue;
                            opStr += " " + callType + (Enum.IsDefined(typeof(BFCallNativeType), callType) ? " \t; " + CallNativeToHintString[callType] : string.Empty);
                            break;
                        case BFInstruction.BeginProcedure:
                            opStr += " " + procedure.Name;
                            break;
                        case BFInstruction.CallProcedure:
                            opStr += " " + procedures[(int)op.Operand.ImmediateValue].Name;
                            break;
                        case BFInstruction.Jump:
                        case BFInstruction.JumpIfFalse:
                            opStr += " @" + jumpLabels[(int)op.Operand.ImmediateValue].Name;
                            break;
                        default:
                            if (op.Operand != null)
                                opStr += " " + op.Operand.ToString();
                            break;
                    }

                    writer.WriteLine("\t" + opStr);
                }
            }
        }