MIPS汇编字符存储报地址错误:为何整型存储可正常运行?
Let's break this down clearly—your integer code runs fine, but the character snippet throws a "Bad address in data/stack" error, and it's not about the .space size alone. Here's what's happening:
Key Differences Between the Two Snippets
- Memory allocation:
- Character code:
x: .space 1sets aside 1 byte (perfect for a single ASCII character). - Integer code:
x: .space 4reserves 4 bytes (a full MIPS word, standard for storing integers).
- Character code:
- How you load values into registers:
- Character code uses
lb $t0, '*'—this is the critical mistake. - Integer code uses
li $t0, 6—this is the correct approach for immediate values.
- Character code uses
Why the Character Code Errors Out
The problem isn't the 1-byte variable—it's your misuse of the lb instruction.
In MIPS, lb (Load Byte) is meant to read a byte from a memory address, not load a constant like a character literal. When you write lb $t0, '*', the assembler converts '*' to its ASCII value (42) and tries to load a byte from memory address 42. That address isn't part of your program's allocated data or stack space, so you get the "Bad address" error.
Your integer code works because li (Load Immediate) is designed exactly for this scenario: it loads a constant value directly into a register without touching memory. li $t0, 6 just sets $t0 to 6—no invalid memory access involved.
Fixing the Character Code
Swap the incorrect lb instruction with li (or addi) to load the character's ASCII value properly. Here's the corrected code:
.data x: .space 1 .text .globl main main: li $t0, '*' # Correct: Load ASCII value of '*' into $t0 sb $t0, x # Store the byte from $t0 into the 1-byte variable x lb $a0, x # Load the character back from x li $v0, 11 # Syscall to print a character syscall jr $ra
This will run without errors: it stores '*' in your 1-byte variable, loads it back, and prints it as expected.
内容的提问来源于stack exchange,提问作者Moi Kko

