如何有效地构建面具

时间:2012-03-24 15:03:10

标签: c# mask

我在c#中只有一个参数,只有一个参数(它是一个覆盖所以我不能改变它的签名以包含更多参数):

read_address(long adr)

其中adr是我想要读取的地址存储器,但我必须传递地址并同时指示要读取的地址是16位还是32位,如果是32位,此外我必须指出是否需要读取大写或小写单词,以便我想知道使用参数adr执行此操作的有效方法。

我想构建一个掩码,例如,如果我想读取地址614(十进制),我可以在之前或之后添加两个数字:

  

10614:第一个数字1表示大小= 32位,第二个数字0表示低位词
  11614:第一个数字1表示大小= 32位,第二个数字1表示大写字母

表示16位,无需指示低位或高位:

00614 = 614将指示16位。

我也可以通过将这两位数字放回去来完成:

61410
61411

因此,当我通过addr参数接收到这个数字时,我必须解析它以确定它是16位还是32位,如果是32位则是低位或高位字。

编辑:

我想我没有好好解释......

例如,可以看出这个方法,read_address,receive和address(addr)要读取。这是从另一个方法method_A调用的,它知道这是16位还是32位,如果是32位,它会分成两个字。更好的例子,对于阅读614:

Method_A(....)
{
   if 16-bit then

   {
       call read_address(620) // Supose 620 is 16 bit
   }

   if 32-bit then

   { 

       // suppose 614 is 32 bit so split into two reads

       call read_address(61410)  // to read first word

       call read_address(61411) // to read second word

   } 

}

所以在read_address中我必须知道它是16位还是32位,如果是32位,我还必须知道它是低位还是高位字。

read_address(long addr)

{

    // decode if addr is 16 or 32 bit and if 32 bit, decode if lower

    // or upper word and do some stuff


    // So suppose it arrives 61410... how to decode it in order to know,

    // address to read is 614 and is 32-bit (1) and I want to read lower word (0)


}

2 个答案:

答案 0 :(得分:3)

你提到“上/下”字只在addr指定一个32位地址时计数 - 我希望你的意思是它只计算16位? (如果不是,你怎么知道值“10”是掩码还是地址?)

我不会对掩码使用小数位,而是将64位分成两个32位数(整数),并使用二进制标记。

然后将示例614作为二进制的64位数字(我希望我得到了字节顺序,但它应该说明情况):

00000010 00000000 00000000 00000000 01100110 00000010 00000000 00000000
|              Mask               | |            Address              |

然后,您可以使用[Flags] enum来定义掩码,并将掩码整数强制转换为该枚举。以下是创建和解析地址的示例:

    public void Main()
    {
        // Some test values.
        ushort address16 = ushort.MaxValue;
        uint address32 = uint.MaxValue;

        // Upper:
        ulong valueUpper = address16;           // Value contains 0x000000000000FFFF
        valueUpper = valueUpper << 48;          // Value contains 0xFFFF000000000000
        valueUpper += (uint)Mask.Upper;         // Value contains 0xFFFF000000000001

        // Lower:
        ulong valueLower = address16;           // Value contains 0x000000000000FFFF
        valueLower = valueLower << 32;          // Value contains 0x0000FFFF00000000
        // No need to set a 0-bit, it is already 0

        // DWord:
        ulong valueDword = address32;           // Value contains 0x00000000FFFFFFFF
        valueDword = valueDword << 32;          // Value contains 0xFFFFFFFF00000000
        valueDword += (uint)Mask.DoubleWord;    // Value contains 0xFFFFFFFF00000010

        ulong addr1 = ParseAddress((long)valueUpper);
        ulong addr2 = ParseAddress((long)valueLower);
        ulong addr3 = ParseAddress((long)valueDword);
    }

    public ulong ParseAddress(long address)
    {
        // Casting to ulong, as negative values don't make sense in addresses or bitwise operations.
        ulong value = (ulong)address;

        // Take the mask from the least significant bits
        Mask mask = (Mask)(value & uint.MaxValue);

        // Shift the mask bytes "off" the addr, get the remaining address. 
        ulong addr = ((ulong)value >> 32);

        // Is the doubleword bit set?
        if ((mask & Mask.DoubleWord) == Mask.DoubleWord)
        {
            return addr;
        }
        else if ((mask & Mask.Upper) == Mask.Upper)
        {
            return (addr >> 16);
        }
        else
        {
            return addr;
        }
    }

    [Flags]
    public enum Mask : uint
    {
        Upper = 1,
        DoubleWord = 2,
    }

答案 1 :(得分:0)

  

它是一个覆盖,因此我无法更改其签名以包含更多内容   参数

虽然您无法覆盖虚拟方法并同时更改其签名,但可以在您的子类中定义一个带有这些额外参数的重载。 e.g:

class SuperClass
{
    public virtual void read_address(long adr)
    {

    }
}

class SubClass : SuperClass
{
    public override void read_address(long adr)
    {
        // call the overload with your default values e.g. 32 and false
        this.read_address(adr, 32, false);
    }

    public void read_address(long adr, int bytesToRead, bool upper)
    {
        // ...
    }
}