led_pattern = (led_pattern << 1) | (led_pattern >> 7)执行顺序

1. 执行步骤分解

cpp 复制代码
unsigned char led_pattern = 0xFE;  // 二进制: 1111 1110

// 第一步:计算 (led_pattern << 1)
// 第二步:计算 (led_pattern >> 7)  
// 第三步:将两个结果进行 | (按位或) 运算
// 第四步:将最终结果赋值给 led_pattern

2. 具体数值演算

以 led_pattern = 0xFE (1111 1110) 为例:

cpp 复制代码
步骤1: led_pattern << 1
       1111 1110 << 1 = 1111 1100
       // 注意:最高位的1移出,最低位补0

步骤2: led_pattern >> 7
       1111 1110 >> 7 = 0000 0001
       // 右移7位,最低位的0移出,高位补0
       // 原最低位的0被丢弃,原来第7位(最高位)的1移到最低位

步骤3: (步骤1的结果) | (步骤2的结果)
       1111 1100  (来自步骤1)
       0000 0001  (来自步骤2)
       ---------- |
       1111 1101  // 最终结果

步骤4: led_pattern = 1111 1101 (0xFD)

3. 完整8次循环演算表

循环次数 原值(二进制) <<1结果 >>7结果 OR结果 新值(十六进制) 点亮位置
初始 1111 1110 1111 1100 0000 0001 1111 1101 0xFD LED1
1次 1111 1101 1111 1010 0000 0001 1111 1011 0xFB LED2
2次 1111 1011 1111 0110 0000 0001 1111 0111 0xF7 LED3
3次 1111 0111 1110 1110 0000 0001 1110 1111 0xEF LED4
4次 1110 1111 1101 1110 0000 0001 1101 1111 0xDF LED5
5次 1101 1111 1011 1110 0000 0001 1011 1111 0xBF LED6
6次 1011 1111 0111 1110 0000 0001 0111 1111 0x7F LED7
7次 0111 1111 1111 1110 0000 0000 1111 1110 0xFE LED0
8次 1111 1110 回到初始值,循环重复 - - - -

4. 运算优先级说明

C语言中运算符优先级(从高到低):

cpp 复制代码
1. 括号 ()          // 最高优先级
2. 移位 << >>       // 优先级较高
3. 按位与 &         // 中等
4. 按位异或 ^       // 中等
5. 按位或 |         // 较低
6. 赋值 =           // 最低优先级

// 因此原表达式等价于:
led_pattern = ((led_pattern << 1) | (led_pattern >> 7));

5. 为什么这样写能实现循环左移?

cpp 复制代码
// 以 8位为例,原始数据 bits[7..0]
// 循环左移1位的结果 = bits[6..0] + bits[7]

// led_pattern << 1  : 得到 bits[6..0] + 0
// led_pattern >> 7  : 得到 0...0 + bits[7]  
// 两者 OR 合并      : 得到 bits[6..0] + bits[7]

// 这就是循环左移(ROL)的效果!

6. 等效的汇编指令

您原来的汇编代码:

cpp 复制代码
ROL AL, 1    ; 循环左移1位

7. 验证代码(可测试执行过程)

cpp 复制代码
#include <stdio.h>

int main() {
    unsigned char led_pattern = 0xFE;
    
    for(int cycle = 0; cycle < 10; cycle++) {
        printf("循环%2d: 0x%02X = ", cycle, led_pattern);
        
        // 显示二进制
        for(int bit = 7; bit >= 0; bit--) {
            printf("%d", (led_pattern >> bit) & 1);
        }
        
        // 执行循环左移
        led_pattern = (led_pattern << 1) | (led_pattern >> 7);
        
        printf("  -> 0x%02X\n", led_pattern);
    }
    
    return 0;
}

输出结果:

bash 复制代码
循环 0: 0xFE = 11111110  -> 0xFD
循环 1: 0xFD = 11111101  -> 0xFB
循环 2: 0xFB = 11111011  -> 0xF7
循环 3: 0xF7 = 11110111  -> 0xEF
循环 4: 0xEF = 11101111  -> 0xDF
循环 5: 0xDF = 11011111  -> 0xBF
循环 6: 0xBF = 10111111  -> 0x7F
循环 7: 0x7F = 01111111  -> 0xFE
循环 8: 0xFE = 11111110  -> 0xFD

关键要点总结

  1. 先计算两边的移位表达式(互不影响,都使用原值)

  2. 再进行按位或运算

  3. 最后赋值给左侧变量

  4. 由于是unsigned char类型,移位超出8位的部分会被丢弃

  5. 整个过程实现了汇编ROL指令的功能

相关推荐
国科安芯1 小时前
83 倍:ASC0108S 在推挽和开漏之间,差的不是速度,是回程
单片机·嵌入式硬件·架构·电平转换·抗辐射
国科安芯4 小时前
从遥控到自治:ASP4644S2B支撑星载电源健康管理与容错配电
网络·单片机·嵌入式硬件·安全·dcdc·低轨卫星·商业航天
rhythm-ring5 小时前
《汽车热管理系统:电子水泵单线PWM双向诊断机制》
单片机·嵌入式硬件·汽车
Dev_XH8 小时前
【成品设计】基于物联网的车间安全生产监控系统设计
stm32·单片机·嵌入式硬件·物联网
xiebs_9 小时前
【无标题】111
单片机
元器件BOM超人10 小时前
GD32E230C8T6 兆易创新Cortex-M23超值型MCU解析:规格参数、替代选型与常见问题
单片机·嵌入式硬件
LONGZHIQIN10 小时前
STM32学习笔记
笔记·stm32·学习·arm
StarsGreen11 小时前
Android 启动流程详解
android·linux·单片机·嵌入式硬件
en.en..11 小时前
AFE:模拟前端,模拟世界通往 MCU 的信号桥梁
单片机·嵌入式硬件
小鳄鱼电气11 小时前
感应电机直接转矩控制传动(AC4 200 HP)仿真说明书
单片机·嵌入式硬件