예제 #1
0
        static void Main(string[] args)
        {
            if (args.Length == 0)
            {
                Console.WriteLine("ubpldir.exe filename");
                Environment.Exit(1);
            }

            using var stream = File.OpenRead(args[0]);
            Span <byte> binary = stackalloc byte[16];
            Span <uint> values = stackalloc uint[4];

            int index = 0;

            while (stream.Read(binary) > 0)
            {
                ToUint(binary, values);
                Mnemonic mnemonic = (Mnemonic)values[0];
                ModRm    modRm    = new ModRm(values[1]);
                string   head     = ToOperandString(modRm.HeadMode, modRm.HeadReg1, modRm.HeadReg2, values[2]);
                string   tail     = ToOperandString(modRm.TailMode, modRm.TailReg1, modRm.TailReg2, values[3]);

                Console.Write("{0:X08}: ", index);
                Console.Write("{0:X08} {1:X08} {2:X08} {3:X08} | ", values[0], values[1], values[2], values[3]);
                Console.WriteLine("{0,-6} {1} {2}", mnemonic, head, tail);

                index += 16;
                binary.Fill(0);
            }
        }
예제 #2
0
파일: Code.cs 프로젝트: jurliyuuri/ubpl
 public Code()
 {
     Mnemonic = Mnemonic.KRZ;
     Modrm    = new ModRm(0U);
     Head     = Operand.F0;
     Tail     = Operand.F0;
 }
        private ModRm ToModRm(Operand opd)
        {
            ModRm modrm = new ModRm();

            if (opd.IsLabel)
            {
                modrm.Reg    = (byte)Register.F0;
                modrm.Mode   = 6;
                modrm.Disp32 = 0;
            }
            else if (opd.IsImm)
            {
                modrm.Reg    = 0;
                modrm.Mode   = GetDispType(opd.Disp.Value);
                modrm.Disp32 = opd.Disp.Value;
            }
            else if (opd.SecondReg.HasValue)
            {
                if (opd.IsAddress)
                {
                    modrm.Reg    = (byte)opd.Reg.Value;
                    modrm.Mode   = (byte)(0b11000 | (byte)opd.SecondReg.Value);
                    modrm.Disp32 = 0U;
                }
                else
                {
                    throw new ArgumentException();
                }
            }
            else if (opd.Disp.HasValue)
            {
                modrm.Reg = (byte)opd.Reg.Value;
                if (opd.IsAddress)
                {
                    modrm.Mode   = (byte)(0b10000 | GetDispType(opd.Disp.Value));
                    modrm.Disp32 = opd.Disp.Value;
                }
                else
                {
                    throw new ArgumentException();
                }
            }
            else
            {
                modrm.Reg    = (byte)opd.Reg.Value;
                modrm.Mode   = (byte)(opd.IsAddress ? 0b10000 : 0);
                modrm.Disp32 = 0U;
            }

            return(modrm);
        }
        private int GetDispLength(ModRm modrm)
        {
            if ((modrm.Mode & 0x18U) == 0x18U || modrm.Mode == 0U)
            {
                return(0);
            }

            switch (modrm.Mode & 7U)
            {
            case 4:
                return(1);

            case 5:
                return(2);

            case 6:
                return(4);

            default:
                return(0);
            }
        }
        private void WriteModRm(BinaryWriter writer, ModRm modrm)
        {
            uint disp = modrm.DispImm;

            writer.Write(modrm.Code);

            if ((modrm.Mode & 0x18) == 0x18)
            {
                return;
            }

            int count;

            switch (modrm.Mode & 0x7)
            {
            case 0x4:
                count = 3;
                break;

            case 0x5:
                count = 2;
                break;

            case 0x6:
                count = 0;
                break;

            default:
                count = 4;
                break;
            }

            for (int i = count; i < 4; i++)
            {
                writer.Write((byte)(disp >> ((3 - i) * 8)));
            }
        }
예제 #6
0
        /// <summary>
        /// バイナリを出力します
        /// </summary>
        /// <returns>変換結果</returns>
        public IReadOnlyList <byte> ToBinaryCode()
        {
            int lifemBinarySize = _lifemValues.Count << 2;
            int binarySize      = (_codes.Count << 4) + lifemBinarySize - (lifemBinarySize & 0xF) + 16;

            List <byte> binaryCode  = new List <byte>(binarySize);
            List <byte> lifemBinary = new List <byte>(lifemBinarySize);
            uint        count       = (uint)_codes.Count * 16U;

            Span <byte> buffer = stackalloc byte[4];

            // lifemのラベル処理,バイナリ化
            foreach (var lifemValue in _lifemValues)
            {
                ToBinary(lifemValue.Value, buffer);

                if (lifemValue.Size == ValueSize.DWORD && (count & 0x3) != 0)
                {
                    uint offset = 4 - (count & 0x3);

                    for (uint i = 0; i < offset; i++)
                    {
                        lifemBinary.Add(0);
                    }

                    count += offset;
                }
                else if (lifemValue.Size == ValueSize.WORD && (count & 0x1) != 0)
                {
                    lifemBinary.Add(0);
                    count += 1;
                }

                if (lifemValue.Labels.Any())
                {
                    foreach (var label in lifemValue.Labels)
                    {
                        label.RelativeAddress = count;
                        _labels.Add(label);
                    }
                }

                switch (lifemValue.Size)
                {
                case ValueSize.BYTE:
                    lifemBinary.Add(buffer[3]);
                    count += 1;
                    break;

                case ValueSize.WORD:
                    lifemBinary.Add(buffer[2]);
                    lifemBinary.Add(buffer[3]);
                    count += 2;
                    break;

                case ValueSize.DWORD:
                    lifemBinary.Add(buffer[0]);
                    lifemBinary.Add(buffer[1]);
                    lifemBinary.Add(buffer[2]);
                    lifemBinary.Add(buffer[3]);
                    count += 4;
                    break;

                default:
                    throw new ApplicationException($"Invalid value: {lifemValue.Size}");
                }
            }

            // コードのバイナリ化
            count = 16U;
            foreach (var code in _codes)
            {
                ModRm modrm = code.Modrm;
                uint  value;

                ToBinary((uint)code.Mnemonic, buffer);
                binaryCode.Add(buffer[0]);
                binaryCode.Add(buffer[1]);
                binaryCode.Add(buffer[2]);
                binaryCode.Add(buffer[3]);

                if (code.Head.HasLabel)
                {
                    switch (modrm.HeadMode)
                    {
                    case OperandMode.REG:
                        modrm.HeadMode = OperandMode.IMM_REG;
                        break;

                    case OperandMode.ADDR_REG:
                        modrm.HeadMode = OperandMode.ADDR_IMM_REG;
                        break;

                    default:
                        break;
                    }
                }

                if (code.Tail.HasLabel)
                {
                    switch (modrm.TailMode)
                    {
                    case OperandMode.REG:
                        modrm.TailMode = OperandMode.IMM_REG;
                        break;

                    case OperandMode.ADDR_REG:
                        modrm.TailMode = OperandMode.ADDR_IMM_REG;
                        break;

                    default:
                        break;
                    }
                }
                ToBinary(code.Modrm.Value, buffer);
                binaryCode.Add(buffer[0]);
                binaryCode.Add(buffer[1]);
                binaryCode.Add(buffer[2]);
                binaryCode.Add(buffer[3]);

                if ((modrm.HeadMode & (~OperandMode.ADDRESS)) == OperandMode.REG)
                {
                    value = 0U;
                }
                else
                {
                    value = code.Head.Immidiate;

                    RegisterValue?register = code.Head.First;
                    if (!(register is null) && register.RelativeAddress != 0)
                    {
                        value -= count;
                    }

                    register = code.Head.Second;
                    if (!(register is null) && register.RelativeAddress != 0)
                    {
                        value -= count;
                    }
                }
                ToBinary(value, buffer);
                binaryCode.Add(buffer[0]);
                binaryCode.Add(buffer[1]);
                binaryCode.Add(buffer[2]);
                binaryCode.Add(buffer[3]);

                if ((modrm.TailMode & (~OperandMode.ADDRESS)) == OperandMode.REG)
                {
                    value = 0;
                }
                else
                {
                    value = code.Tail.Immidiate;

                    RegisterValue?register = code.Tail.First;
                    if (!(register is null) && register.RelativeAddress != 0)
                    {
                        value -= count;
                    }

                    register = code.Tail.Second;
                    if (!(register is null) && register.RelativeAddress != 0)
                    {
                        value -= count;
                    }
                }
                ToBinary(value, buffer);
                binaryCode.Add(buffer[0]);
                binaryCode.Add(buffer[1]);
                binaryCode.Add(buffer[2]);
                binaryCode.Add(buffer[3]);

                count += 16;
            }

            binaryCode.AddRange(lifemBinary);

            int length = binaryCode.Count & 0xF;

            for (int i = 16 - length; i > 0; i--)
            {
                binaryCode.Add(0);
            }

            return(new ReadOnlyCollection <byte>(binaryCode));