2012-03-24 41 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) 
    { 
     // ... 
    } 
}