MIPS 中的初始堆栈指针不是 0x7fffffff

initial stack pointer is not 0x7fffffff in MIPS

我已经使用 QtSPIM 模拟器组装了一段简短的 MIPS 汇编代码。我正在附加完成代码:

.text
.globl main
main:
 subu $sp,$sp,32 # Stack frame is 32 bytes long
 sw $ra,20($sp) # Save return address
 sw $fp,16($sp) # Save old frame pointer
 addiu $fp,$sp,28 # Set up frame pointer
 li $a0,10 # Put argument (10) in $a0
 jal fact # Call factorial function
 la $a0,$LC # Put format string in $a0
 move $a1,$v0 # Move fact result to $a1
 lw $ra,20($sp) # Restore return address
 lw $fp,16($sp) # Restore frame pointer
 addiu $sp,$sp,32 # Pop stack frame
 jr $ra # Return to caller
 
 .rdata
$LC:
.ascii "The factorial of 10 is %d\n[=10=]0"
 
 .text
fact:
 subu $sp,$sp,32 # Stack frame is 32 bytes long
 sw $ra,20($sp) # Save return address
 sw $fp,16($sp) # Save frame pointer
 addiu $fp,$sp,28 # Set up frame pointer
 sw $a0,0($fp) # Save argument (n)
 lw $v0,0($fp) # Load n
 bgtz $v0,$L2 # Branch if n > 0
 li $v0,1 # Return 1
 jr $L1 # Jump to code to return

$L2:
  lw $v1,0($fp) # Load n
  subu $v0,$v1,1 # Compute n - 1
  move $a0,$v0 # Move value to $a0
  jal fact # Call factorial function
  lw $v1,0($fp) # Load n
  mul $v0,$v0,$v1 # Compute fact(n-1) * n
  
$L1: # Result is in $v0
  lw $ra, 20($sp) # Restore $ra
  lw $fp, 16($sp) # Restore $fp
  addiu $sp, $sp, 32 # Pop stack
  jr $ra # Return to caller

我正在阅读的有关 MIPS 的书说,程序 运行 时的初始堆栈指针应指向内存中的位置 0x7FFFFFFF。 MIPS 模拟器中的堆栈指针 ($sp) 是第 2 条指令的首次访问。$sp 指向地址 0x7ffffe10,如 $a1 寄存器 (0x7ffffe10 = 7ffffe14 - 4 ) 所示。为什么堆栈指针地址是 0x7ffffe10 而不是 0x7FFFFFFF?什么代码改变了它?

首先,0x7FFFFFFF 不是 MIPS 堆栈指针的合理地址,因为它是奇数。 MIPS 堆栈指针指向字,因此应该是 4 的偶数倍。

其次,QtSPIM 以类似于 UNIX 进程的方式设置模拟的初始堆栈 — 它将命令行参数和环境变量放在堆栈上。

建议你看看数据部分的堆栈,你很可能会看到环境的字符串。 (单击 Data 选项卡,在 运行 模拟的第一条指令之前,然后查看 User Stack 内存区域。)

运行ning QtSPIM on windows,例如,我看到的字符串与从命令行执行 set 命令时看到的相同字符串 shell cmd (cmd.exe).

如果您使用“运行 Parameters”菜单项(来自 QtSPIM 菜单:“Simulator”)添加“要传递给程序的命令行参数”,您在此处键入的任何字符串也会出现在堆栈中在环境字符串前面。这也将更改模拟使用的初始堆栈指针值。