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

相关推荐
Deitymoon2 小时前
STM32——串口通信发送字符串
stm32·单片机·嵌入式硬件
这波不该贪内存的10 小时前
裸机开发VS单片机:架构与实战对比
单片机
山羊硬件Time11 小时前
自动化管理Linux的好工具:shell script
linux·嵌入式硬件·硬件工程师·基带工程·硬件开发
神一样的老师11 小时前
【兆易创新GD32VW553开发板试用】红外遥控接入天气时钟实战
驱动开发·单片机·嵌入式硬件
asjodnobfy11 小时前
Π型滤波电路
嵌入式硬件·硬件工程
多看多敲多思考13 小时前
华润微CS32ME10 MCU使用教程(2)---CS32ME10之UART串口模块使用
stm32·单片机·嵌入式硬件·mcu
神一样的老师13 小时前
【兆易创新GD32VW553开发板试用】天气时钟设计与调试实战
单片机·嵌入式硬件·物联网
国科安芯14 小时前
核电站仪控与监测系统中抗辐射 MCU 芯片应用研究
单片机·嵌入式硬件·macos·无人机·cocos2d·核电站
黑白园14 小时前
STM32系统时钟由72M修改为36M验证示例
stm32·单片机·嵌入式硬件