using System; namespace VMdemo.Core { public static class AddressTranslatorUtils { public static AddressParts SplitVirtualAddress(ulong virtualAddress, int vaBits, int offsetBits) { if (vaBits <= 0 || vaBits > 64) { throw new ArgumentOutOfRangeException(nameof(vaBits), "vaBits 必须在 1 到 64 之间。"); } if (offsetBits < 0 || offsetBits >= vaBits) { throw new ArgumentOutOfRangeException(nameof(offsetBits), "offsetBits 必须满足 0 <= offsetBits < vaBits。"); } var vaMask = GetBitMask(vaBits); if (vaBits < 64 && (virtualAddress & ~vaMask) != 0UL) { throw new ArgumentOutOfRangeException(nameof(virtualAddress), "virtualAddress 超出 vaBits 可表示范围。"); } var vpnBits = vaBits - offsetBits; GetPageTableBitLayout(vpnBits, out _, out var l2Bits); var offset = virtualAddress & GetBitMask(offsetBits); var vpn = virtualAddress >> offsetBits; var l2Index = vpn & GetBitMask(l2Bits); var l1Index = vpn >> l2Bits; return new AddressParts(vpn, offset, l1Index, l2Index); } public static void GetPageTableBitLayout(int vpnBits, out int l1Bits, out int l2Bits) { if (vpnBits <= 0) { throw new ArgumentOutOfRangeException(nameof(vpnBits), "vpnBits 必须是正整数。"); } l1Bits = (vpnBits + 1) / 2; l2Bits = vpnBits / 2; } public static string FormatSplitResult( ulong virtualAddress, int vaBits, int offsetBits, AddressParts parts) { return $"VA={virtualAddress}, VPN={parts.Vpn}, Offset={parts.Offset}, L1={parts.L1Index}, L2={parts.L2Index}, vaBits={vaBits}, offsetBits={offsetBits}"; } private static ulong GetBitMask(int bits) { if (bits <= 0) { return 0UL; } if (bits >= 64) { return ulong.MaxValue; } return (1UL << bits) - 1UL; } } }