gpt4 book ai didi

c - AVR C 中字符数组的按位移位

转载 作者:太空宇宙 更新时间:2023-11-04 02:39:59 25 4
gpt4 key购买 nike

最初我需要串行发送和接收一些数据。数据包长度为 48 位。对于较短的数据包(32 位),我可以这样做:

unsigned long data=0x12345678;

for(i=0;i<32;i++){
if(data & 0x80000000)
setb_MOD;
else
clrb_MOD;
data <<= 1;
}

这段代码编译真让我满意:

        code<<=1;
ac: 88 0f add r24, r24
ae: 99 1f adc r25, r25
b0: aa 1f adc r26, r26
b2: bb 1f adc r27, r27
b4: 80 93 63 00 sts 0x0063, r24
b8: 90 93 64 00 sts 0x0064, r25
bc: a0 93 65 00 sts 0x0065, r26
c0: b0 93 66 00 sts 0x0066, r27

在我需要扩展数据包(到 48 位)后,我需要移动一个数组:

unsigned char data[6]={0x12,0x34,0x56,0x78,0xAB,0xCD};

for(i=0;i<48;i++){
if(data[5] & 0x80)
setb_MOD;
else
clrb_MOD;
for(j=5;j>0;j--){
data[j]<<=1;
if(data[j-1] & 0x80)
data[j]+=1;
}
data[0] <<= 1;
}

编译后的代码稍微取决于优化设置,但通常它会执行我在 C 中的命令:

        for(j=5;j>0;j--){
code[j]<<=1;
a8: 82 91 ld r24, -Z
aa: 88 0f add r24, r24
ac: 80 83 st Z, r24
if(code[j-1]&0x80)
ae: 9e 91 ld r25, -X
b0: 97 fd sbrc r25, 7
b2: 13 c0 rjmp .+38 ; 0xda <__vector_2+0x74>
clrb_MOD;
}
else{
setb_MOD;
}
for(j=5;j>0;j--){
b4: 80 e0 ldi r24, 0x00 ; 0
b6: a3 36 cpi r26, 0x63 ; 99
b8: b8 07 cpc r27, r24
ba: b1 f7 brne .-20 ; 0xa8 <__vector_2+0x42>
code[j]<<=1;
if(code[j-1]&0x80)
code[j]+=1;
}

如您所见,没有明显的(对于人类而言)解决方案来逐字节移动数组。

我想跳过内联汇编程序的注入(inject),因为我并没有真正掌握这项技术,而且我真的不明白如何在 Asm 中处理 C 变量。有没有其他选择?

最佳答案

如果您知道您的输入小于 64 位,您可以执行类似的操作(假设 stdint.h 可用,否则转换为 unsigned long long 等):

union BitShifter
{
uint64_t u64;
uint32_t u32[2];
uint16_t u16[4];
uint8_t u8[8];
};

union BitShifter MyBitshifter;

MyBitShifter.u64 <<= 1;

编译器应该使用最好的指令来实现这一点(可能是两个 32 位移位和一些其他逻辑来将位从一个字移到另一个字。当然,后端可能是懒惰的,并且以字节为单位...

根据 AVR 的字节顺序,您必须以正确的顺序调整字节以正确输出位顺序。

关于c - AVR C 中字符数组的按位移位,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33023466/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com