2012-03-24 58 views
0

我在C#中的方法仅具有1个参数(它是一个覆盖,所以我不能改变其签名,以将更多的参数):如何建立一个掩模有效

read_address(long adr) 

其中ADR是地址存储器I想要读取,但我必须传递地址并同时指出要读取的地址是16位还是32位,如果是32位,此外我必须指出是否要读取上部或下部字,所以我想知道使用参数adr来实现这一点的有效方法。

我已经想建立一个掩模,例如,如果我想读地址614(十进制),我可以添加两个数字之前或背面:

10614:第一个数字1表示尺寸= 32位和第二个0 =低字
11614:第一个数字1表示尺寸= 32位和第二个1 =高位字

为表示16位,没有必要以指示下或上,以便:

0061 4 = 614将指示16位。

我也可以把这些两位数回做到了这一点:

所以,当我通过addr参数获得该号码我必须分析它知道这是一个16或32位,如果是低位或高位字,则为32位。

编辑:

我想我没有解释好...

例如,图这个方法,READ_ADDRESS,接收和地址(地址)来读取。这是从另一个方法method_A调用的,它知道这是16位还是32位,如果是32位,它会分成两个字。更好的例子,对于读614:在READ_ADDRESS

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 

    } 

} 

所以我要知道这是否是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) 


} 
+0

请不要在“c# - ”等前加上标题。这就是标签的用途。 – 2012-03-24 15:05:48

+0

这里真的有问题吗?如果有的话,我会说答案取决于'adr'的值的可能范围。例如。对于一个32位的值,增加10000会导致大量的麻烦。 – 2012-03-24 15:23:13

+0

没有这种方法*作为重载*可以正常工作的情况。调用者*具有*知道如何正确地破坏地址,所以该方法可以工作。所以它*有*知道这个特定的覆盖将被调用。在那时,使它成为一个覆盖就没有意义了,只需添加一个新的方法即可。 – 2012-03-24 15:29:37

回答

3

你提到的“上/高”字,只有当指定地址的32位地址计数 - 但愿你的意思是只计算在16位? (如果不是,你怎么知道值“10”是一个掩码或地址?)

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

的例子614二进制64位号码将被(我希望我得到了字节序的权利,但应说明情况):

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

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

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, 
    } 
+0

我一直在考虑你的解决方案,我认为它更易于维护和高效,但我不太了解你...你能否提供一个非常小的例子,用掩码构造地址(大小写为双字),然后提取地址并检查它是低位还是高位双字?非常感谢您的帮助 – user304602 2012-03-24 21:12:01

+0

@ user304602看到我的修改后的工作示例。再次,我希望低/高的东西适用于16位的值,而不是32位的,否则你就被搞砸了。 – 2012-03-25 13:02:48

0

它是一个覆盖这样虽然不能覆盖虚方法,我不能改变它的签名,以纳入更多 参数

和在同一时间更改其签名,你可以在你的子类中定义一个带有这些额外参数的重载。例如:

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) 
    { 
     // ... 
    } 
}