export const levels = [ // ===== Level 1: 认识寄存器 ===== { id: 1, title: '认识寄存器', subtitle: '小机器人的记忆槽', icon: '🤖', description: '学习 MOV 指令给寄存器赋值', tutorial: [ { title: '什么是寄存器?', text: 'CPU 是计算机的大脑,而**寄存器**是它手边的小抽屉 —— 速度最快的存储空间!我们的机器有 8 个寄存器:**R0** 到 **R7**。', }, { title: 'MOV 指令', text: '`MOV` 把一个数字放进寄存器。注意数字前面要加 **#** 号,表示"这是一个数值":', code: 'MOV R0, #42 ; 把 42 放进 R0\nMOV R1, #100 ; 把 100 放进 R1', }, { title: 'HLT 指令', text: '程序最后要写 `HLT`(halt = 停止),告诉机器"运行结束!"', code: 'MOV R0, #42\nHLT', }, ], goal: '把数字 **42** 放进 **R0** 寄存器', initialState: {}, testCases: [{ init: {}, expected: { registers: { R0: 42 } } }], hints: [ 'MOV 的格式:MOV 寄存器, #数字', '试试:MOV R0, #???', '答案:MOV R0, #42 然后 HLT', ], starThresholds: [2, 3, 5], starterCode: '; 把 42 放进 R0 寄存器\n; 提示:数字前面要加 # 号\n\n\nHLT', showMemory: false, }, // ===== Level 2: 数据搬运工 ===== { id: 2, title: '数据搬运工', subtitle: '寄存器之间的复制', icon: '📦', description: '学习在寄存器之间复制数据', tutorial: [ { title: '寄存器间复制', text: 'MOV 也能把一个寄存器的值**复制**到另一个(这时不需要 # 号):', code: 'MOV R1, R0 ; 把 R0 的值复制到 R1', }, { title: '复制,不是移动!', text: '虽然叫 "MOV"(移动),但其实是**复制**。执行后 R0 的值不变,R1 变成和 R0 一样。', }, ], goal: 'R0 已经有值 **7**,把它复制到 **R1** 和 **R2**', initialState: { registers: { R0: 7 } }, testCases: [{ init: {}, expected: { registers: { R0: 7, R1: 7, R2: 7 } } }], hints: [ 'MOV 寄存器, 寄存器 —— 把右边复制到左边', 'MOV R1, R0 可以把 R0 复制到 R1', '答案:MOV R1, R0 / MOV R2, R0 / HLT', ], starThresholds: [3, 4, 6], starterCode: '; R0 = 7\n; 把 R0 复制到 R1 和 R2\n\n\nHLT', showMemory: false, }, // ===== Level 3: 加减法 ===== { id: 3, title: '加减法', subtitle: '三操作数的威力', icon: '➕', description: '学习 ADD 和 SUB 指令', tutorial: [ { title: 'ADD —— 加法(三操作数)', text: 'ARM 风格的加法很酷:**三个操作数**!第一个放结果,后两个是被运算的值:', code: 'ADD R2, R0, R1 ; R2 = R0 + R1\nADD R0, R0, #10 ; R0 = R0 + 10', }, { title: 'SUB —— 减法', text: 'SUB 同理,也是三操作数:', code: 'SUB R2, R0, R1 ; R2 = R0 - R1\nSUB R0, R0, #5 ; R0 = R0 - 5', }, { title: '好处', text: '三操作数的好处:可以直接把结果放到新的寄存器,**不用先复制**!', }, ], goal: 'R0=**15**,R1=**27**,计算 R0+R1 存入 **R2**(R0和R1不变)', initialState: { registers: { R0: 15, R1: 27 } }, testCases: [{ init: {}, expected: { registers: { R0: 15, R1: 27, R2: 42 } } }], hints: [ 'ADD 第一个参数放结果,后两个参数相加', 'ADD R2, R0, R1 —— 结果存入 R2', '答案:ADD R2, R0, R1 / HLT', ], starThresholds: [2, 3, 5], starterCode: '; R0=15, R1=27\n; 计算 R0 + R1,结果存入 R2\n\n\nHLT', showMemory: false, }, // ===== Level 4: 乘法与除法 ===== { id: 4, title: '乘法与除法', subtitle: '更强的算术能力', icon: '✖️', description: '学习 MUL 和 DIV 指令', tutorial: [ { title: 'MUL —— 乘法', text: 'MUL 也是三操作数:', code: 'MOV R0, #6\nMOV R1, #7\nMUL R2, R0, R1 ; R2 = 6 × 7 = 42', }, { title: 'DIV —— 除法(取整)', text: 'DIV 做整数除法(只留整数部分):', code: 'MOV R0, #100\nMOV R1, #4\nDIV R2, R0, R1 ; R2 = 100 ÷ 4 = 25', }, ], goal: '计算 **6 × 7** 存入 R0,**100 ÷ 4** 存入 R1', initialState: {}, testCases: [{ init: {}, expected: { registers: { R0: 42, R1: 25 } } }], hints: [ '先 MOV 数字到寄存器,再 MUL/DIV', 'MUL R0, R2, R3 可以把 R2×R3 的结果放到 R0', '答案:MOV R2, #6 / MOV R3, #7 / MUL R0, R2, R3 / MOV R2, #100 / MOV R3, #4 / DIV R1, R2, R3 / HLT', ], starThresholds: [7, 9, 12], starterCode: '; 计算 6×7 存入 R0\n; 计算 100÷4 存入 R1\n\n\nHLT', showMemory: false, }, // ===== Level 5: 位运算魔法 ===== { id: 5, title: '位运算魔法', subtitle: '0和1的秘密', icon: '🔮', description: '学习 AND、ORR、EOR、MVN 指令', tutorial: [ { title: '二进制世界', text: '计算机内部用 **0** 和 **1** 存储一切。42 的二进制是 `00101010`。右边面板会显示每个寄存器的二进制值!', }, { title: 'AND —— 都是1才是1', text: 'AND 逐位比较,两个都是 1 结果才是 1。可以用来"提取"某些位:', code: '; 11111111 (255)\n; AND 00001111 (15)\n; = 00001111 (15)\nAND R0, R0, #15', }, { title: '其他位运算', text: '**ORR** = 有一个1就是1 (OR)\n**EOR** = 不同才是1 (XOR)\n**MVN** = 全部翻转 (NOT)', code: 'ORR R0, R0, #240 ; 设置高4位\nEOR R0, R0, #255 ; 翻转低8位\nMVN R0, R0 ; 翻转所有位', }, ], goal: 'R0 = **255** (二进制 11111111),用 AND 提取**低4位**,使 R0 变成 **15**', initialState: { registers: { R0: 255 } }, testCases: [{ init: {}, expected: { registers: { R0: 15 } } }], hints: [ 'AND 用来保留某些位,把其他位清零', '低4位的掩码是 15(二进制 00001111)', '答案:AND R0, R0, #15 / HLT', ], starThresholds: [2, 3, 5], starterCode: '; R0 = 255 (二进制 11111111)\n; 用 AND 提取低4位\n\n\nHLT', showMemory: false, }, // ===== Level 6: 移位操作 ===== { id: 6, title: '移位操作', subtitle: '位的舞蹈', icon: '↔️', description: '学习 LSL 和 LSR 指令', tutorial: [ { title: 'LSL —— 逻辑左移', text: '所有位向左移,右边补0。**左移1位 = 乘以2**,左移3位 = 乘以8:', code: '; 5 = 00000101\nLSL R0, R0, #1 ; 00001010 = 10 (×2)\nLSL R0, R0, #1 ; 00010100 = 20 (×2)', }, { title: 'LSR —— 逻辑右移', text: '所有位向右移,左边补0。**右移1位 = 除以2**:', code: 'MOV R0, #40\nLSR R0, R0, #1 ; 20 (÷2)\nLSR R0, R0, #2 ; 5 (÷4)', }, { title: '程序员的技巧', text: '在真实的 ARM 处理器中,移位比乘除快得多!`LSL R0, R0, #3` 比 `MUL R0, R0, #8` 高效。', }, ], goal: 'R0 = **5**,只用**移位操作**把它变成 **40**(40 = 5 × 8 = 5 × 2³)', initialState: { registers: { R0: 5 } }, testCases: [{ init: {}, expected: { registers: { R0: 40 } } }], hints: [ '8 = 2³,乘以8就是左移3位', 'LSL R0, R0, #3', '就这一条指令!', ], starThresholds: [2, 3, 5], blockedOps: ['MUL', 'DIV'], starterCode: '; R0 = 5\n; 用 LSL 让 R0 变成 40(不能用 MUL)\n\n\nHLT', showMemory: false, }, // ===== Level 7: 内存读写 ===== { id: 7, title: '内存读写', subtitle: '打开更大的空间', icon: '💾', description: '学习 LDR 和 STR 指令', tutorial: [ { title: '什么是内存?', text: '寄存器只有8个,太少了!**内存**像一排256格的柜子,每格有编号(0-255)。', }, { title: 'LDR —— 从内存读取', text: '先把地址放进寄存器,再用 `LDR` 从那个地址读数据:', code: 'MOV R1, #0 ; 地址 = 0\nLDR R0, [R1] ; R0 = 内存[0]', }, { title: 'STR —— 写入内存', text: '`STR` 把寄存器的值写到内存:', code: 'MOV R1, #5 ; 地址 = 5\nSTR R0, [R1] ; 内存[5] = R0', }, { title: '偏移寻址', text: '还可以加偏移量:`[R1, #4]` 表示地址 R1+4:', code: 'MOV R1, #0\nLDR R0, [R1, #0] ; 内存[0]\nLDR R2, [R1, #1] ; 内存[1]', }, ], goal: '内存[0]=**10**,内存[1]=**20**,计算它们的和存入 **内存[2]**', initialState: { memory: { 0: 10, 1: 20 } }, testCases: [{ init: {}, expected: { memory: { 2: 30 } } }], hints: [ '先用 LDR 把内存值读到寄存器,算完用 STR 写回', 'MOV R3, #0 设基地址,LDR R0, [R3, #0] 读第一个值', '答案:MOV R3, #0 / LDR R0, [R3, #0] / LDR R1, [R3, #1] / ADD R2, R0, R1 / STR R2, [R3, #2] / HLT', ], starThresholds: [6, 8, 10], starterCode: '; 内存[0]=10, 内存[1]=20\n; 计算它们的和,存入内存[2]\n;\n; 提示:先 MOV 一个地址到寄存器\n; 然后用 LDR/STR 读写内存\n\n\nHLT', showMemory: true, memoryRange: [0, 15], }, // ===== Level 8: 比较与跳转 ===== { id: 8, title: '比较与跳转', subtitle: '让程序会做决定', icon: '🔀', description: '学习 CMP 和条件分支指令', tutorial: [ { title: '到目前为止...', text: '程序都是从头到尾顺序执行。但有了**分支**,程序就能做决定了!', }, { title: 'CMP —— 比较', text: '`CMP` 比较两个值,记住比较结果(不会改变它们的值):', code: 'CMP R0, #10 ; 比较 R0 和 10', }, { title: '条件分支', text: '比较后用 **B** (Branch=分支) 跳转:', code: 'BEQ label ; 等于则跳(Equal)\nBNE label ; 不等则跳(Not Equal)\nBGT label ; 大于则跳(Greater Than)\nBLT label ; 小于则跳(Less Than)\nB label ; 无条件跳', }, { title: '标签', text: '**标签**是代码里的记号,分支指令跳到标签位置。标签后面加冒号:', code: 'CMP R0, #10\nBGT big\nMOV R1, #0 ; R0 <= 10\nB done ; 跳过下面\nbig:\nMOV R1, #1 ; R0 > 10\ndone:\nHLT', }, ], goal: 'R0=**15**。如果 R0 > 10 则 R1 = **1**;否则 R1 = **0**', initialState: { registers: { R0: 15 } }, testCases: [ { init: { registers: { R0: 15 } }, expected: { registers: { R1: 1 } } }, { init: { registers: { R0: 5 } }, expected: { registers: { R1: 0 } } }, { init: { registers: { R0: 10 } }, expected: { registers: { R1: 0 } } }, ], hints: [ '先设 R1=#0(默认),再比较 R0 和 10', '如果 R0 > 10,跳到标签把 R1 改成 1', '答案:MOV R1, #0 / CMP R0, #10 / BLE done / MOV R1, #1 / done: HLT', ], starThresholds: [5, 7, 9], starterCode: '; 如果 R0 > 10,则 R1 = 1\n; 否则 R1 = 0\n\n\nHLT', showMemory: false, }, // ===== Level 9: 循环 ===== { id: 9, title: '循环', subtitle: '重复的力量', icon: '🔄', description: '用分支指令创建循环', tutorial: [ { title: '什么是循环?', text: '循环让一段代码**反复执行**。在汇编中,循环就是**跳回前面的标签**!', }, { title: '循环结构', text: '①初始化 ②做事 ③更新计数器 ④判断+跳回:', code: 'MOV R4, #0 ; ① 初始化\nloop: ; 循环开始\n ADD R4, R4, #1 ; ②③ 计数+1\n CMP R4, #5 ; ④ 到5了吗?\n BLE loop ; 没到就跳回\nHLT', }, { title: '注意!', text: '忘了更新计数器 = **死循环**(别担心,超过10000步会自动停止)。', }, ], goal: '计算 **1+2+3+...+10** 的和存入 **R0**(答案是55)', initialState: {}, testCases: [{ init: {}, expected: { registers: { R0: 55 } } }], hints: [ 'R0 累加结果,R4 做计数器(1到10)', '循环体:ADD R0, R0, R4 / ADD R4, R4, #1 / CMP R4, #10 / BLE loop', '完整:MOV R0, #0 / MOV R4, #1 / loop: ADD R0, R0, R4 / ADD R4, R4, #1 / CMP R4, #10 / BLE loop / HLT', ], starThresholds: [7, 9, 12], starterCode: '; 计算 1+2+3+...+10\n; 结果存入 R0\n;\n; 提示:用一个寄存器做计数器\n\n\nHLT', showMemory: false, }, // ===== Level 10: 终极挑战 ===== { id: 10, title: '终极挑战', subtitle: '寻找最大值', icon: '🏆', description: '综合运用所有技能!', tutorial: [ { title: '最后一关!', text: '你已经学会了寄存器、算术、位运算、内存、分支和循环。现在把**所有技能**结合起来!', }, { title: '挑战说明', text: '内存地址 0-4 存了5个数字。你要找到**最大值**和它的**位置**。需要:循环 + 内存读取 + 比较分支。', }, { title: '解题思路', text: '1. 假设第一个数最大(R0=内存[0],R1=位置0)\n2. 循环检查剩余的数\n3. 如果发现更大的,更新最大值和位置\n4. 直到检查完全部5个数', code: '; 伪代码:\n; R0 = max = mem[0]\n; R1 = maxIdx = 0\n; for R4 = 1 to 4:\n; R5 = mem[R4]\n; if R5 > R0: R0=R5, R1=R4', }, ], goal: '内存[0..4] 有5个数,找出**最大值**存入 **R0**,其**位置**存入 **R1**', initialState: { memory: { 0: 5, 1: 3, 2: 8, 3: 1, 4: 7 } }, testCases: [ { init: { memory: { 0: 5, 1: 3, 2: 8, 3: 1, 4: 7 } }, expected: { registers: { R0: 8, R1: 2 } }, }, { init: { memory: { 0: 1, 1: 9, 2: 4, 3: 9, 4: 2 } }, expected: { registers: { R0: 9, R1: 1 } }, }, ], hints: [ 'R0=最大值, R1=位置, R4=循环计数器, R5=当前值, R3=基地址', '用 LDR R5, [R3, R4] 不行的话,可以用 R3 当地址:MOV R3, R4 / LDR R5, [R3]', '循环体:把 R4 当地址读内存 → CMP R5, R0 → BLE skip → 更新 R0,R1 → skip: ADD R4, R4, #1 → CMP R4, #5 → BLT loop', ], starThresholds: [12, 15, 20], starterCode: '; 内存[0..4] = [5, 3, 8, 1, 7]\n; 找最大值存入 R0,位置存入 R1\n;\n; 提示:用 R4 做循环变量\n; 用 MOV + LDR 读取内存\n\n\nHLT', showMemory: true, memoryRange: [0, 15], }, ]