2010-11-11 43 views
2

我無法鏡像一個字節,也無法通過Google找到任何技術。 我試圖做到的是反映一個字節, 又名內容: 千萬= 00000001 10010111 = 11101001 等等鏡像字節/ X86嵌入式程序集(在Visual Studio 2010中)

我使用的組件嵌入到下,在Visual Studio 2010中 謝謝在先進的你的時間和幫助

編輯:速度沒有必要,很抱歉沒有指出。它必須以彙編書寫。

+0

爲什麼必須把它用匯編,如果速度是沒有意義?如果速度不重要,爲什麼不直接用班次和口罩直接寫下來呢?如果你不知道如何做,那你爲什麼使用匯編程序? – 2010-11-11 23:40:41

+1

@Oli:如果你仔細看看他的問題,他們都是特定於x86彙編語言 - 我想他正在上課...... – 2010-11-11 23:48:10

回答

5

只要你不關心速度,你可以通過你的源代碼中的carry(rcr)和你目的地中的carry(rcl)向左旋轉(反之亦然)。

如果您希望速度更快,只需使用表查找(因爲您一次只需要一個字節,它只會是一個256字節的表)。

+0

非常好,非常感謝你! – Quentin 2010-11-11 23:45:22

0

我認爲你已經降低到了達到速度後的彙編程度。如果是這樣,最快的方法是通過查找表。在這一點上,你不需要彙編器(因爲它在C中速度會更快)。請注意,許多嵌入式平臺(通常是DSP)將具有本地位反轉指令。但是這可能對你沒有多大用處!

0

我不確定您是否需要使用程序集。既然你已經用C嵌入彙編,你可以用C簡單的查找表和完全跳過裝配...

byte const mirror[256] = { 
0x00, 0x80, 0x40, 0xc0, ... 
}; 
0

鴻溝和征服者:除以2字節,翻轉的左半部分,翻轉右半部分,然後翻轉兩半。例如,10000100

分:1000 0100

左:0001

權:0010

兩者:0010 0001

這降低了從表的大小256字節到16字節,因此您可以輕鬆地驗證它是否正確翻轉,但需要額外的計算。

+0

-1:這將需要更多的操作,而不是簡單地一次交換一個位。 – 2010-11-11 23:04:44

+0

它旨在減少查表的大小,而不是實際執行班次。 – ldav1s 2010-11-11 23:07:23

+0

你應該在你的回答中提及那個! – 2010-11-11 23:39:01

2

對於一個字節,請使用查找表。該表將適合L1緩存,並且速度很快。

對於更長的值,人們可以使用移位和屏蔽,這樣做的速度比一次只做一點更快。例如,對於32位值:

uint32_t bit_reverse_32(uint32_t x) 
{ 
    x = ((x & 0x55555555) << 1) | ((x >> 1) & 0x55555555); 
    x = ((x & 0x33333333) << 2) | ((x >> 2) & 0x33333333); 
    x = ((x & 0x0F0F0F0F) << 4) | ((x >> 4) & 0x0F0F0F0F); 
    x = ((x & 0x00FF00FF) << 8) | ((x >> 8) & 0x00FF00FF); 
    x = (x << 16) | (x >> 16); 
    return x; 
} 

的這個C代碼轉換成彙編轉換留給作爲一個練習,或者甚至更好,留下作爲C編譯器工作,這確實是種的東西爲了生計。

0

這是一個不推薦的解決方案,只是爲了好玩。我檢查了一些轉換,但不是全部。桌面查找絕對是一種可行的方式,旋轉進出的可接受答案是我過去使用的。

下面的解決方案使用乘法將低4位分隔爲高位,然後使用2 ** n-1數字的模數將位滾回低位。

這裏有一個版本的一個步驟,但使用64位乘法: http://graphics.stanford.edu/~seander/bithacks.html#ReverseByteWith64BitsDiv

#include <stdlib.h> 
#include <stdio.h> 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    int x, y; 

    for (x=0; x<256; x++) 
    { 

     // magic number/bit distribution way of flipping 4 bits 
     // y = ((x * 0x00082082 & 0x01122408) % 255) >> 2; 
     _asm 
     { 
      mov ecx, x   // get operand 
      mov eax, ecx  // get lower 4 bits into eax 
      and eax, 0x0f 
      mov ebx, 0x82082 // get magic multiplier into ebx 
      imul eax, ebx  // distribute lower into upper bits 
      and eax, 0x1122408 // and out the bits we want 
      mov edx, 0   // initilialize upper DX:AX bits 
      mov edi, 0xff  // modulo divisor 
      idiv edi   // divide, leaving remainder in DX 
      shr edx, 2   // adjust result 
      mov esi, edx  // stash first half of flipped bits 
      shl esi, 4 

      // repeat with upper bits 
      mov eax, ecx 
      shr eax, 4 
      imul eax, ebx 
      and eax, 0x1122408 
      mov edx, 0 
      idiv edi 
      shr edx, 2 
      or edx, esi 

      mov y, edx 
     }; 

     printf("x %08x reverse %08x\n", x, y); 
    } 

    return 0; 
} 
相關問題