/// <summary>
 /// メインメモリにアクセスします
 /// </summary>
 /// <param name="address">メモリアドレス</param>
 /// <returns>指定したメモリアドレスに格納されているbyte</returns>
 public byte this[UInt32 address] {
     // メモリへのストア
     set {
         ulong phy_addr = GetPhysicalAddr(address, MemoryAccessMode.Write);
         CheckPmp(phy_addr, MemoryAccessMode.Write);
         mainMemory[phy_addr] = value;
         if (ToHostTrapAddress.Contains(phy_addr))
         {
             throw new HostAccessTrap(value);
         }
         else if (FromHostTrapAddress.Contains(phy_addr))
         {
             // 外部割り込みを有効/無効にする
             reg.CSRegisters.Eip ^= 0xb00U;
         }
     }
     // メモリからのロード
     get {
         ulong phy_addr = GetPhysicalAddr(address, MemoryAccessMode.Read);
         CheckPmp(phy_addr, MemoryAccessMode.Read);
         if (ToHostTrapAddress.Contains(phy_addr))
         {
             throw new HostAccessTrap(mainMemory[phy_addr]);
         }
         return(mainMemory[phy_addr]);
     }
 }
        /// <summary>
        /// 指定したアドレスから命令をフェッチする
        /// </summary>
        /// <param name="addr">命令のアドレス</param>
        /// <returns>32bit長 Risc-V命令</returns>
        public UInt32 FetchInstruction(UInt32 address)
        {
            ulong phy_addr = GetPhysicalAddr(address, MemoryAccessMode.Execute);

            CheckPmp(phy_addr, MemoryAccessMode.Execute);
            if (ToHostTrapAddress.Contains(phy_addr))
            {
                throw new HostAccessTrap(BitConverter.ToUInt32(mainMemory, (int)phy_addr));
            }

            return(BitConverter.ToUInt32(mainMemory, (int)phy_addr));
        }