3

我正在研究一个没有硬件划分的 Cortex M0 cpu,所以每次我划分一些东西时,都会使用 GCC 库函数。现在我最常做的除法之一是除以 256,将短裤转换为字节。有什么方法可以比默认的 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 -mthumbGCC 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]将保留一个字节的值,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 回答