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”)添加“要传递给程序的命令行参数”,您在此处键入的任何字符串也会出现在堆栈中在环境字符串前面。这也将更改模拟使用的初始堆栈指针值。
我已经使用 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”)添加“要传递给程序的命令行参数”,您在此处键入的任何字符串也会出现在堆栈中在环境字符串前面。这也将更改模拟使用的初始堆栈指针值。