You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

微处理器架构与编程课程代码求助:掩码部分理解困惑

解读RISC-V指令模拟器中的掩码与位提取逻辑

我目前处于大学倒数第二个学期,正在学习《微处理器架构与编程》课程。教授编写了一段模拟RISC-V指令执行的代码,我能理解寄存器打印和指令传入的操作,但搞不懂其中的掩码相关逻辑,尤其是get_bits函数的实现,恳请帮忙解读。

完整代码

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

uint32_t Instruction_Memory[0x2000];
uint32_t PC = 0;

uint32_t Registers[32];

uint32_t Data_Memory[0x3000];

uint32_t get_instruction(uint32_t input){
   uint32_t temp = input/4;
   return Instruction_Memory[temp];
}

void print_registers() {
   for (int i = 0; i < 4; i++) {
       for (int j = 0; j < 8; j++) {
           printf("x%d: %x 	", i*8+j, Registers[i*8+j]);
       }
       printf("\n");
   };
};

uint32_t get_bits(uint32_t input, int start, int numberOfBits){
   uint32_t t4 = input >> start;
   uint32_t mask = (1 << numberOfBits) - 1;

   t4 = mask & t4;
//    printf("input : %x, start : %d, nob : %d, mask : %x\n", input, start, numberOfBits, mask);
   return t4;
}

int main(){
   PC = 0x1000;

//    x5
   Registers[5] = 6;
//    x9
   Registers[9] = 0x2004;

   Data_Memory[0x2000] = 10;

   Instruction_Memory[0x1000 / 4] = 0xFFC4A303;
   Instruction_Memory[0x1004 / 4] = 0x0064A423;
   Instruction_Memory[0x1008 / 4] = 0x0062E233;

   uint32_t instruction = get_instruction(0x1000);

   printf("Instruction = 0x%x\n\r", instruction);

   print_registers();
   uint32_t A1 = get_bits(instruction, 15, 5);
   printf("A1 = %x\n\r", A1);

   return 0;
}

核心逻辑解读

这段代码是一个极简的RISC-V指令模拟器,重点拆解你困惑的掩码与位提取部分:

1. get_bits函数:从32位指令中提取指定范围的位

这个函数的作用是从32位的input指令中,提取从start位开始的连续numberOfBits位,核心就是掩码的生成与使用:

  • 右移对齐

    uint32_t t4 = input >> start;
    

    把输入的32位指令向右移动start位,让目标提取位移动到二进制数的最低位区域。比如要提取第15位开始的5位,右移15位后,这5位就到了第0-4位的位置。

  • 生成掩码

    uint32_t mask = (1 << numberOfBits) - 1;
    

    这是掩码生成的关键:

    • 1 << numberOfBits:把数字1左移numberOfBits位,比如提取5位时,左移5位得到二进制100000(十六进制0x20)。
    • 减1后,二进制变为011111(十六进制0x1F)——低numberOfBits位全为1,高位全为0。这个掩码的作用就是精准"筛选"出我们需要的位。
  • 按位与提取目标位

    t4 = mask & t4;
    

    按位与的特性是:只有对应位都为1时结果才是1,否则为0。用掩码和右移后的结果做按位与,就能清零所有高位,只保留我们需要的低numberOfBits位。

2. 结合代码实例验证

main函数中调用get_bits(instruction, 15, 5),其中instruction是0xFFC4A303(RISC-V的LW指令):

  • 右移15位后,t4的值为0x1FF89
  • 掩码是(1<<5)-1=0x1F
  • 按位与后得到0x1FF89 & 0x1F = 0x9,对应寄存器x9的编号,和代码中Registers[9]被赋值为0x2004完全匹配——这正是LW指令中用作基地址的寄存器,符合RISC-V指令格式。

其他辅助逻辑说明

  • get_instruction:RISC-V指令是4字节对齐的,所以PC地址除以4得到指令内存数组的索引(数组每个元素存储一条4字节指令)。
  • 指令内存中的三条指令分别是:
    • 0xFFC4A303:LW指令,从x9-4地址加载数据到x6
    • 0x0064A423:SW指令,把x6的数据存储到x9+4地址
    • 0x0062E233:ADD指令,将x5和x6的值相加后存回x5

内容的提问来源于stack exchange,提问作者Nicholas Akkerer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 00:01:11