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指令的功能

相关推荐
Hello-FPGA9 分钟前
Camera Link 与 CoaXPress 技术对比 如何选择你的相机接口
单片机·嵌入式硬件
Digitally14 分钟前
如何快速将文件从电脑传输到平板电脑
stm32·嵌入式硬件·电脑
2601_9583529016 分钟前
嵌入式对讲收音降噪难题根治方案|AP-0316语音模组原理、实测与落地教程
人工智能·嵌入式硬件·语音识别·ai降噪·回音消除·音频处理模块
济61735 分钟前
BMS系统专栏:电池状态监控任务
嵌入式硬件·嵌入式·bms电池系统管理
济6171 小时前
BMS系统专栏: BMS_ProtectTask 电池保护任务
嵌入式硬件·嵌入式·bms电池管理
XTIOT6661 小时前
多形态护照 OCR 读取器传输机制、识别算法与行业落地技术对比
大数据·人工智能·嵌入式硬件·物联网·ocr
欢乐熊嵌入式编程1 小时前
选型避坑:ESP32 vs STM32+模组 vs NB-IoT,不同场景怎么选
stm32·单片机·嵌入式硬件·物联网·esp32·嵌入式iot
拎得清n3 小时前
寄存器点灯
单片机·嵌入式硬件
破晓单片机13 小时前
067、STM32项目分享:语音儿童学习书桌系统
stm32·单片机·嵌入式硬件
欢乐熊嵌入式编程13 小时前
嵌入式 + MQTT:数据上传到阿里云实战(从0到1完整教程)
stm32·单片机·mqtt·freertos·嵌入式架构·efr32