Raspberry Pi 4汇编实现随机数发生器出现段错误求助
汇编实现LFSR随机数发生器触发段错误的问题
我用汇编实现了基于LFSR的随机数发生器,通过Vim编写代码、GCC编译运行,但始终触发段错误(Segmentation Fault)。GDB调试显示错误发生在set_leds函数,回溯指向generate_random分支处。我已用Python脚本验证GPIO引脚功能正常,也尝试过重建文件目录、拆分代码排查,问题仍未解决。
以下是我的汇编代码:
.section .data seed: .word OxA5A5A5A5 // Initial seed for the LFSR .section .text .global main main: // Start and initialization of the seed LDR RO, =seed // Load address of seed into RO LDR R1, [RO] // Load seed value into R1 generate_random: // Perform LFSR LSR R2, R1, #1 // Logical shift right AND R3, R1, #1 // AND with 1 to get LSB EOR R2, R2, R3, LSL #31 // XOR with LSB shifted to MSB MOV R1, R2 // Move result back to R1 // Store new seed STR R1, [RO] // Store updated seed back to memory // Use lower bits of the seed to determine LED output AND R4, R1, #0xFF // Mask lower 8 bits BL set_leds // Branch to set_leds function wait_button: // Wait for button press LDR R5, =0xFE200000 // Base address ADD R6, R5, #0x34 // GPIO Pin Level Register LDR R6, [R6] // Load GPIO level register LDR R7, =0x0400 // Load constant (1 << 10) into R7 AND R6, R6, R7 // Check GPIO pin 10 (button) BEQ wait_button // Loop until button is pressed // Delay loop for debouncing MOV R7, #0x3F0000 // Load delay value delay_loop: SUBS R7, R7, #1 // Decrement delay counter BNE delay_loop // Loop until delay is finished B generate_random // Go back to generate_random // Function to set the LEDs set_leds: PUSH {R4-R7, LR} // Save the return address and used registers // Setup for the GPIO LDR R6, =0xFE200000 // Base address for GPIO on Raspberry Pi 4 // Set GPIO pins 2-9 to output LDR R7, =0x000003FC // Load constant (0b11111111 << 2) into R7 STR R7, [R6, #0x04] // Set as output // Clear the GPIO pins LDR R7, =0x000003FC // Load constant (Ob11111111 << 2) into R7 STR R7, [R6, #0x28] // Clear the pins // Set the GPIO pins based on R4 MOV R7, R4 AND R7, R7, #0xFF LDR R8, =0x000000FC // Load constant (0b11111111 << 2) into R8 ORR R7, R7, R8 STR R7, [R6, #0x1C] // Set the pins POP {R4-R7, LR} // Restore the registers and return address BX LR // Return from function
问题排查与修复方案
1. 寄存器拼写错误
代码中多处将ARM寄存器R0误写为RO(字母O),这会导致程序访问错误的寄存器,进而操作非法内存地址,直接触发段错误。需将所有RO替换为R0。
2. 立即数拼写错误
初始种子OxA5A5A5A5使用了字母O开头,正确的十六进制前缀应为数字0,需修正为0xA5A5A5A5。
3. 代码段语法错误
.section .text .global main属于语法错误,需拆分为两行:
.section .text .global main
否则汇编器无法正确识别全局符号定义,导致程序入口异常。
4. 寄存器上下文破坏
set_leds函数中使用了R8寄存器,但PUSH/POP列表中未包含R8。根据ARM APCS调用规范,R4-R11属于非临时寄存器,必须在函数开头保存、结尾恢复,否则会破坏调用者的上下文。需修改栈操作指令:
PUSH {R4-R8, LR} // ...函数代码... POP {R4-R8, LR}
5. GPIO控制逻辑错误
原代码中通过ORR R7, R7, R8设置LED引脚的逻辑错误,正确做法是将R4的低8位直接左移2位,映射到GPIO2-9的位置:
MOV R7, R4 AND R7, R7, #0xFF LSL R7, R7, #2 // 将低8位移到GPIO2-9对应的位 STR R7, [R6, #0x1C]
6. 运行权限问题
Raspberry Pi的GPIO寄存器属于硬件资源,普通用户无访问权限,必须以root权限运行程序,否则会触发段错误。运行时需执行:
sudo ./你的程序名
修复后的完整代码
.section .data seed: .word 0xA5A5A5A5 // 修正立即数拼写错误 .section .text .global main // 拆分语法错误的行 main: // 初始化种子 LDR R0, =seed // 修正RO为R0 LDR R1, [R0] // 修正RO为R0 generate_random: // LFSR生成随机数 LSR R2, R1, #1 AND R3, R1, #1 EOR R2, R2, R3, LSL #31 MOV R1, R2 // 保存新种子 STR R1, [R0] // 修正RO为R0 // 获取低8位用于LED控制 AND R4, R1, #0xFF BL set_leds wait_button: // 等待按键按下 LDR R5, =0xFE200000 ADD R6, R5, #0x34 LDR R6, [R6] LDR R7, =0x0400 AND R6, R6, R7 BEQ wait_button // 消抖延迟 MOV R7, #0x3F0000 delay_loop: SUBS R7, R7, #1 BNE delay_loop B generate_random // LED控制函数 set_leds: PUSH {R4-R8, LR} // 新增保存R8 LDR R6, =0xFE200000 // 设置GPIO 2-9为输出 LDR R7, =0x000003FC STR R7, [R6, #0x04] // 清除引脚状态 LDR R7, =0x000003FC STR R7, [R6, #0x28] // 根据R4设置引脚 MOV R7, R4 AND R7, R7, #0xFF LSL R7, R7, #2 // 把低8位移到GPIO2-9的位置 STR R7, [R6, #0x1C] POP {R4-R8, LR} // 恢复R8 BX LR
内容的提问来源于stack exchange,提问作者Raging Storm
相关产品推荐
相关产品推荐

