2010-05-03 48 views
2

我正在將一些彙編代碼轉換爲C,以便能夠將其與當前編譯環境一起使用。如何在C中執行這些操作?

我已經達到了2個操作我不知道如何翻譯成C.任何人都知道該怎麼做?

在兩者中,offset是一個無符號的32位整數,而shift是一個有符號的整數值。 C_FLAG是一個bool。

OP1:

__asm { 
    __asm mov ecx, shift 
    __asm ror offset, cl 
} 

OP2:

__asm { 
    __asm bt dword ptr C_FLAG, 0 
    __asm rcr offset, 1 
} 

非常感謝您對您的專業知識。

PS:我不是原來的開發商,我也見過很多x86彙編代碼...

+0

你問這些操作是做什麼的?或者你問如何用C表達它們?或兩者? – 2010-05-03 20:24:45

+0

有兩種,現在我知道第一個是旋轉右操作;但我不知道第二個是幹什麼的,也不知道如何將它轉換爲C代碼。 – 2010-05-03 20:33:26

+0

你是對的,第一個是旋轉右操作。第二個似乎是在x86程序集中實現ARM RRX(向右旋轉,擴展/旋轉右擴展)。你可以看到這兩個解釋在這裏:http://www.mitchellwebdesign.com/arm/lecture4/lecture4-3-4.html – Xandy 2010-05-03 22:24:44

回答

0

假設標記不用於保持持久狀態(這是一個合理的假設),OP1等效於:

/* Precondition: `*offset` is in range 0..0xFFFFFFFF */ 
void inline op1(unsigned long *offset, int shift) 
{ 
    shift = ((unsigned)shift) % 32; 

    if (shift) 
     *offset = ((*offset >> shift) | (*offset << (32 - shift))) & 0xFFFFFFFFUL; 
} 

和OP2相當於:

/* Precondition: `*offset` is in range 0..0xFFFFFFFF */ 
void inline op2(unsigned long *offset, unsigned long C_FLAG) 
{ 
    *offset = (*offset >> 1) | ((C_FLAG & 1) << 31); 
} 

(開系統有32位long,前提條件自動滿足)。

+0

非常感謝,經過一番閱讀,我認爲這是正確的答案。我真的不知道的是爲什麼在第二操作中的bt操作,如果它是通過進位權進行旋轉不會足夠嗎? – 2010-05-05 00:18:38

+0

@Juan Antonio:'BT'是實際設置*進位標誌的地方 - 在這種情況下,它將進位標誌設置爲'C_FLAG'的第0位,這是一個32位內存操作數。 – caf 2010-05-05 00:30:28

+0

感謝您的解釋,進位標誌可能來自以前的操作。 – 2010-05-05 00:44:19

0

對於位移,按照您的第一個示例,使用<<運算符。在C語言中沒有換行,通常被稱爲轉動。你必須自己實現的操作:

unsigned char carry; 
carry = byte & 0x80; // Save the Most Significant bit for 8-bit byte. 
byte <<= 1; // Left shift by one, insert a 0 as the least significant bit. 
byte |= carry; // Put the rotated bit back into the byte. 

一些處理器也有通過旋轉進行操作將旋轉在接下來的移進位值。這假定carry是一個全局變量。要測試C語言中的位,您將使用&(二進制AND運算符)和可能的~運算符(否定)。要在8位字節測試最顯著位:

if (byte & 0x80) 
    { 
     // bit is a 1 
    } 
    else 
    { 
     // bit is a 0 
    } 

說了這麼多,你將不得不找出爲什麼攜帶標誌(C_FLAG)的使用和設計圍繞它不同的系統。一般來說,進位位在彙編語言函數之外是無效的,它使用的是一些緊密耦合的彙編語言函數可能違反這個規則。在那種情況下,重寫彙編語言而不是調試它。重新設計整個程序!

+2

無論如何,這是左旋轉和你的進位結束在錯誤的地方。 – nategoose 2010-05-03 21:52:18

0

用於第二運算

__asm bt dword ptr C_FLAG, 0 

將進位標誌C_FLAG(因此1或0)

__asm rcr offset, 1 

被旋轉進位左其是使用進位標誌爲33位旋轉第33位。 (並且結果將第33位放在進位標誌中。這(我認爲)是一樣的

offset = offset << 1 + C_FLAG ? 1:0 

(除非你不在乎以後進位標誌)

編輯 - 由於某種原因,我在讀RCR爲RCL。所以更喜歡

offset = offset >> 1 | (C_FLAG ? 1<<31 : 0) 
+0

'1UL << 31'更好('1 << 31'給出'int'不能表示該數字的系統中未定義的行爲,而這在'unsigned long'的保證範圍內)。 – caf 2010-05-04 00:49:07

0

雖然或多或少覆蓋,我會做這種方式:

OP 1:這是在offsetshift地方向右旋轉操作。在C語言中它可能是這樣的:

offset = (offset >> shift) | (offset << (WORD_LENGTH - shift); 

您可以用sizeof(void *) * 8例如獲得了這個詞的長度。


OP 2:我認爲這個操作是在x86彙編中實現RRX操作。這是另一種類型的旋轉右移操作,其中進位標誌用於提供要移位的33位量。在C語言中它可能是這樣的:

offset = (C_FLAG << 31) | (offset >> 1); 

哪裏C_FLAG是進位標誌,你會發現更多關於你的代碼確實正在使用什麼bool值的。