MIPS Mars4.5代码问题:无法提取并保存算术项首个数字
Hey Clara! As a fellow MIPS learner, I totally get how easy it is to trip up on the little details of function flow and register usage. Let's walk through what's causing your code to fail and fix it step by step.
Key Issues in Your Current Code
Let's break down the main problems preventing your output from showing up:
1. Broken Function Flow (No Return Instructions)
Your is_num and read_num blocks are written inside handle_one_line but don't use jr $ra to return to the caller. This means after is_num checks a character, it doesn't jump back to where it was called—it just keeps executing the next line of code. For example:
- When
is_numfinds a digit, it sets$v0=1, but then immediately runs thenotdigitcode that sets$v0=0. Sois_numalways returns 0, making yourread_numskip straight toZeichenwithout reading any digits. read_numalso never returns, which messes up the execution flow ofhandle_one_line.
2. Missing Null Terminator for Strings
The syscall 4 (print string) requires your string to end with a null byte (\0). Your code stores characters into link_chars but never adds this terminator—so the system doesn't know where the string ends, resulting in no output or garbage data.
3. Saved Register Mismanagement
In MIPS, registers like $s1 are "saved registers"—you need to save their original value on the stack before modifying them, then restore them before returning. Otherwise, you might overwrite values used by other parts of your program.
4. Incomplete handle_one_line Function
You saved $ra at the start of handle_one_line but never restored it or returned to the main function with jr $ra. While your main loop uses j m_loop, this still leaves your execution flow in an undefined state.
Corrected Code
Here's the fixed version of your handle_one_line function (plus fixes to is_num and read_num), with comments explaining each change:
handle_one_line: # Save return address AND $s1 (since we'll modify it) on the stack addi $sp, $sp, -8 sw $ra, 0($sp) sw $s1, 4($sp) la $s1, link_chars # Initialize pointer to our buffer at the start jal read_num # Call read_num to collect digits Zeichen: # Add null terminator to the end of our collected string sb $zero, ($s1) # Print the collected digits li $v0, 4 la $a0, link_chars # Use the buffer's base address, not $s1 (which is at the end now) syscall # Restore saved registers and return to main lw $s1, 4($sp) lw $ra, 0($sp) addi $sp, $sp, 8 jr $ra # Critical: return to the caller (main) # --- Helper Function: is_num --- is_num: jal get_current_char # Get current character in $v0 li $t0, '0' bltu $v0, $t0, is_num_notdigit li $t0, '9' bltu $t0, $v0, is_num_notdigit # It's a digit: return 1 in $v0 li $v0, 1 jr $ra # Return to caller is_num_notdigit: # Not a digit: return 0 in $v0 li $v0, 0 jr $ra # Return to caller # --- Helper Function: read_num --- read_num: jal is_num beq $v0, $zero, read_num_done # Exit if not a digit jal get_current_char # $v0 holds the ASCII value of the character, so we can store it directly sb $v0, ($s1) addi $s1, $s1, 1 # Move pointer forward jal advance_cursor j read_num # Keep reading digits read_num_done: jr $ra # Return to handle_one_line
Additional Notes for Your Main Function
Just a quick check: make sure line_buffer and cursor_pos are properly declared in your data section, like this:
.data line_buffer: .space 8192 cursor_pos: .word 0 link_chars: .space 20 # Adjust size based on how many digits you expect
Why This Works
- Proper Function Returns: Each helper function uses
jr $rato jump back to where it was called, so execution flows correctly. - Null Terminator: We add
sb $zero, ($s1)before printing, so the system recognizes the end of the string. - Saved Register Handling: We save and restore
$s1on the stack to avoid breaking other parts of your program. - Fixed
is_numLogic: Nowis_numreturns 1 for digits and 0 otherwise, soread_numactually collects digits instead of skipping straight to the print step.
Give this a try—you should now see the first sequence of digits from your input printed out!
内容的提问来源于stack exchange,提问作者Clara Valentine

