如何操作 MIPS 代码和使用堆栈指针?
How to manipulate MIPS code and use stack pointers?
所以,我最近编写了一个代码来计算 C 代码和 MIPS 代码中二进制 1 的数量。我在 C 中通过使用余数并递增 count_one 变量来完成此操作。在 MIPS 中,我做了同样的程序,但我移动了数字的字节,直到它计算出所有的 1。但是,我想尝试学习如何使用指针,但我似乎无法掌握这个概念。我的MIPS代码如下:
.data
prompt: .asciiz "Enter a integer: "
.text
li $v0,4
la $a0, prompt
syscall
li $v0,5
syscall
move $s0,$v0
j count
count:
beq $s0,0, exit
andi $t0,$s0,1
add $t1,$t1,$t0
srl $s0,$s0,1
j count
exit:
move $a0,$t1
la $v0,1
syscall
li $v0,10
syscall
我得到了这个完整的 MIPS 代码,但我不确定指针在 MIPS 中是如何完全工作的,阅读后我仍然不明白。关于如何实现指针有什么建议吗?
最常见的命令决定了数据的含义。
例如伪代码
inc $a0
此命令递增寄存器 $a0
中的数据,与数字
一样使用它
lw $s1, 0($a0)
此命令从寄存器指向的内存中加载数据$a0
像指针一样使用它
这里是一个示例代码,它在 MIPS 中转换流动的 C 代码。
为了保存和恢复保留的寄存器,它在堆栈上创建了一些位置,然后使用 sw
和 lw
来保存和恢复这些寄存器。
int leaf_example(int g, int h, int i, int j) {
int f;
f = (g + h) - (i + j);
return f;
}
.text
main:
addi $a0,[=10=],1 #argument 0 = 1
addi $a1,[=10=],2 #argument 1 = 2
addi $a2,[=10=],3 #argument 2 = 3
addi $a3,[=10=],4 #argument 3 = 4
jal leaf # call function leaf
add $s0,$v0,$zero # return value
li $v0,10
syscall
leaf:
addi $sp, $sp, -12 #adjust stack to make room for 3 items
sw $s0, 8($sp) #save register $s0 for use in memory location 8
sw $t0, 4($sp) #save register $t0 for use in memory location 4
sw $t1, 0($sp) #save register $t1 for use in memory location 0
add $t0, $a0, $a1 #register $t0 contains $a0 + $a1
add $t1, $a2, $a3 #register $t1 contains $a2 + $a3
sub $s0, $t0, $t1 #$t0 = $t0 - $t1 -> $t0 = ($a0 + $a1) - ($a2 + $a3)
add $v0, $s0, $zero #copy $s0 to return register $v0
#Before returning, we restore three original values
#of registers we pushed onto stack by popping them
lw $t1, 0($sp) #restore register $t1 for caller
lw $t0, 4($sp) #restore register $t0 for caller
lw $s0, 8($sp) #restore register $s0 for caller
addi $sp, $sp, 12 #adjust stack to delete 3 items
jr $ra #jump back to calling routine
所以,我最近编写了一个代码来计算 C 代码和 MIPS 代码中二进制 1 的数量。我在 C 中通过使用余数并递增 count_one 变量来完成此操作。在 MIPS 中,我做了同样的程序,但我移动了数字的字节,直到它计算出所有的 1。但是,我想尝试学习如何使用指针,但我似乎无法掌握这个概念。我的MIPS代码如下:
.data
prompt: .asciiz "Enter a integer: "
.text
li $v0,4
la $a0, prompt
syscall
li $v0,5
syscall
move $s0,$v0
j count
count:
beq $s0,0, exit
andi $t0,$s0,1
add $t1,$t1,$t0
srl $s0,$s0,1
j count
exit:
move $a0,$t1
la $v0,1
syscall
li $v0,10
syscall
我得到了这个完整的 MIPS 代码,但我不确定指针在 MIPS 中是如何完全工作的,阅读后我仍然不明白。关于如何实现指针有什么建议吗?
最常见的命令决定了数据的含义。
例如伪代码
inc $a0
此命令递增寄存器 $a0
中的数据,与数字
lw $s1, 0($a0)
此命令从寄存器指向的内存中加载数据$a0
像指针一样使用它
这里是一个示例代码,它在 MIPS 中转换流动的 C 代码。
为了保存和恢复保留的寄存器,它在堆栈上创建了一些位置,然后使用 sw
和 lw
来保存和恢复这些寄存器。
int leaf_example(int g, int h, int i, int j) {
int f;
f = (g + h) - (i + j);
return f;
}
.text
main:
addi $a0,[=10=],1 #argument 0 = 1
addi $a1,[=10=],2 #argument 1 = 2
addi $a2,[=10=],3 #argument 2 = 3
addi $a3,[=10=],4 #argument 3 = 4
jal leaf # call function leaf
add $s0,$v0,$zero # return value
li $v0,10
syscall
leaf:
addi $sp, $sp, -12 #adjust stack to make room for 3 items
sw $s0, 8($sp) #save register $s0 for use in memory location 8
sw $t0, 4($sp) #save register $t0 for use in memory location 4
sw $t1, 0($sp) #save register $t1 for use in memory location 0
add $t0, $a0, $a1 #register $t0 contains $a0 + $a1
add $t1, $a2, $a3 #register $t1 contains $a2 + $a3
sub $s0, $t0, $t1 #$t0 = $t0 - $t1 -> $t0 = ($a0 + $a1) - ($a2 + $a3)
add $v0, $s0, $zero #copy $s0 to return register $v0
#Before returning, we restore three original values
#of registers we pushed onto stack by popping them
lw $t1, 0($sp) #restore register $t1 for caller
lw $t0, 4($sp) #restore register $t0 for caller
lw $s0, 8($sp) #restore register $s0 for caller
addi $sp, $sp, 12 #adjust stack to delete 3 items
jr $ra #jump back to calling routine