3

ハードウェア分割のないCortex M0 cpuで作業しているので、何かを分割するたびにGCCライブラリ関数が使用されます。現在、私が最もよく行う除算の 1 つは、256 で除算して、short をバイトに変換することです。デフォルトの GCC ライブラリよりも効率的に (ビットシフトなどで) これを行う方法はありますか?

4

3 に答える 3

7

あなたのコメントによると、-32768 を 0 にマップし、32767 を 255 にマップする必要があります。したがって、必要な式は次のとおりです。

short s = /* input value */;
unsigned char c = (unsigned char) ((s + 32768) / 256);

他のコメント投稿者は、右シフトまたはその他のさまざまな戦術を使用して 256 で割ることができると述べていますが、これは本当です。これの合理的なバージョンは次のようになります。

unsigned char c = (unsigned char) ((s + 32768) >> 8);

ただし、そのような最適化は必要ありません。GCC は、定数による除算演算を特別なケースの実装に変換することについて非常にスマートです。この場合、これらの両方をまったく同じコードにコンパイルします (-O2 -mcpu=cortex-m0 -mthumbおよび GCC 4.7.2 でテスト済み)。

    mov     r3, #128
    lsl     r3, r3, #8
    add     r0, r0, r3
    lsr     r0, r0, #8
    uxtb    r0, r0

あまりにも賢くしようとすると(他の回答のユニオンまたはポインターキャストの例のように)、混乱してさらに悪い結果になる可能性があります-特にそれらはメモリロードによって機能し、32768を追加すると、すでに持っていることを意味しますレジスタ内の値。

于 2013-02-03T19:06:53.953 に答える
2

ポインタをキャストするだけです。

unsigned char *bytes = (unsigned char*)&yourvalue;

今、bytes[0]あなたの値の1バイトを保持し、bytes[1]他のバイトを保持します。順序はシステムのエンディアンに依存します

于 2013-02-03T16:57:37.597 に答える
1

次のように使用できますunion

#include <stdio.h>

union Word {
    struct {
        unsigned char high;
        unsigned char low;
    } byte;
    unsigned short word;
};

int main(int argc, char **argv) {

    union Word word;
    word.word = 0x1122;

    printf("L = 0x%x, H = 0x%x", word.byte.low, word.byte.high);

    return 0;
}
于 2013-02-03T17:09:04.277 に答える