使用 Assembly 在 pos n 的字节中插入一个位
Insert a bit in a byte at pos n with Assembly
有没有比普通 C 语言更快的汇编语言方法?
这是 C:
中函数的原型
uint8_t InsertBit(uint8_t input, uint16_t idx, uint8_t insbit)
函数应该return新值。我在嵌入式手臂皮质 M 上工作。
C 例程大约有 18 条指令。
C 例程:
__attribute__((optimize("O1")))
uint8_t InsertBit(uint8_t input, uint16_t idx, uint8_t insbit)
{
//Split the input into two parts, one shifted and one not
uint8_t bottom = input;
uint8_t top = (input << 1);
//insert a '0' or '1' before the shifted part
if (insbit)
top |= (1 << idx);
else
top &= (~(1 << idx));
//keep the top bits of top
top &= (-1 << idx);
//keep the bottom bits of bottom
bottom &= ~(-1 << idx);
//combine the two parts.
return (bottom | top);
}
uint8_t InsertBit(uint8_t input, uint16_t idx, uint8_t insbit)
{
return (input + (input & (-1 << idx))) | (insbit << idx);
}
备注:
- x+x 将 x 乘以 2,等同于将其左移 1
- 我们想插入一点,所以我们只将 x 的最高位添加到原始 x。
abcdefgh x
abc00000 x & (-1 << 5) // idx is 5
--------(+)
abc0defgh <--- one bit inserted at position 5
此处abc + abc
结果为abc0
,即abc
左移1位
同时让 defgh
独自一人,不移动
然后只需 or
在适当位置的所需位即可。
相当简单,没有条件逻辑
Erik 的方法(通过添加输入的屏蔽版本将插入点上方的位左移)可以表示为
uint8_t InsertBit(uint8_t input, uint16_t idx, uint8_t insbit)
{
return ((insbit + (input >> idx)) << idx) + input;
}
由于自由移位,在 ARM 上基本上编译为两条指令:
add r2, r2, r0, lsr r1
add r0, r0, r2, lsl r1
and r0, r0, #255
bx lr
有没有比普通 C 语言更快的汇编语言方法?
这是 C:
中函数的原型uint8_t InsertBit(uint8_t input, uint16_t idx, uint8_t insbit)
函数应该return新值。我在嵌入式手臂皮质 M 上工作。 C 例程大约有 18 条指令。
C 例程:
__attribute__((optimize("O1")))
uint8_t InsertBit(uint8_t input, uint16_t idx, uint8_t insbit)
{
//Split the input into two parts, one shifted and one not
uint8_t bottom = input;
uint8_t top = (input << 1);
//insert a '0' or '1' before the shifted part
if (insbit)
top |= (1 << idx);
else
top &= (~(1 << idx));
//keep the top bits of top
top &= (-1 << idx);
//keep the bottom bits of bottom
bottom &= ~(-1 << idx);
//combine the two parts.
return (bottom | top);
}
uint8_t InsertBit(uint8_t input, uint16_t idx, uint8_t insbit)
{
return (input + (input & (-1 << idx))) | (insbit << idx);
}
备注:
- x+x 将 x 乘以 2,等同于将其左移 1
- 我们想插入一点,所以我们只将 x 的最高位添加到原始 x。
abcdefgh x
abc00000 x & (-1 << 5) // idx is 5
--------(+)
abc0defgh <--- one bit inserted at position 5
此处
abc + abc
结果为abc0
,即abc
左移1位同时让
defgh
独自一人,不移动然后只需
or
在适当位置的所需位即可。相当简单,没有条件逻辑
Erik 的方法(通过添加输入的屏蔽版本将插入点上方的位左移)可以表示为
uint8_t InsertBit(uint8_t input, uint16_t idx, uint8_t insbit)
{
return ((insbit + (input >> idx)) << idx) + input;
}
由于自由移位,在 ARM 上基本上编译为两条指令:
add r2, r2, r0, lsr r1
add r0, r0, r2, lsl r1
and r0, r0, #255
bx lr