MIPS中如何正确使用指针?
How to use pointer correctly in MIPS?
我写了一个程序,它接受一些数字的输入并循环遍历每个数字。如果当前数字大于我最后一个最大数字,那么它应该交换最大值。如果它在最后一个数字(在我的字符串的末尾),它应该退出。
我正在尝试调试并且我明白,我并不真正理解指针是如何工作的以及何时必须在我的寄存器周围使用括号。
代码如下:
.data
first: .word 5, 6, -128, -5, 260, 34, 3, 20, -1
last: .word 44
max: .space 4
.text
lw $t0, first
lw $t1, last
lw $t5, max
sw $t5, $t0
loop:
beq $t0, $t1, ex
addi $t0, $t0, 4
bgt $t0, $t5, swapmax
j loop
swapmax:
lw $t0, ($t5)
ex:
lw $t5, max
li $v0, 10
syscall
我在哪里需要括号,为什么?
程序编译成功,但出现错误:
attempt to execute non-instruction at 0x800000180
这个错误是什么意思?
什么是指针?
指针是指向内存位置的东西。我们使用指针将值放在内存位置。例如在 C:
int max;
int *ptr = &max;
*ptr = 22; // max = 22
在上面的示例中,ptr 指向内存位置 (max),我们通过取消引用它来通过 ptr
更改 max 的值。
如何在MIPS中正确使用它们?
要理解这一点,您需要了解指令语法以及每条指令采用的操作数。显然,我们无法在一个答案中完成所有说明,所以我只会向您展示一些,以便您了解:
lw register, memory_location
sw register, memory_location
la register, memory_location
lw
从内存中加载一个字到寄存器中。示例:
lw $t0, first
lw $t0, ($t5) # this is like, int t0 = *t5
sw
将 register 中的值存储到 memory location 中。示例:
sw $t0, max # max = t1
sw $t0, ($t5) # *t5 = t0
la
将内存位置的地址加载到寄存器中。
la $t5, max # int *t5 = &max
现在让我们看看您的代码中的错误。这里:
lw $t5, max
上面会将 max
的值加载到 $t5
中。您似乎创建了 max
来存储最大值。在这里加载它似乎毫无意义,因为它甚至不包含任何内容。您想使用 la
:
加载它的地址
la $t5, max #load address of max variable into $t5
继续前进,我们看到这条指令:
sw $t5, $t0
这不会assemble。这将导致错误。 sw
第一个操作数(源)是寄存器,第二个操作数是“内存位置”,而不是寄存器。
sw register, memory_location
所以,如果你想存储一些东西,你会这样做:
sw $t5, ($t0) #store value inside $t5 at the 'address' inside $t0.
# Assume:
# $t5 = 23
# $t0 = 0x5555
# After executing this instruction, memory location 0x5555 would have value 23 in it
这只是解释。在上面的代码中,您分配了 $t0 = first
。它甚至没有指向内存位置!但是,如果您执行 la $t5, max
.
,$t5 将有一个内存位置
所以,我假设你想做:
sw $t0, ($t5)
# After executing this, 'max' == $t0 because $t5 is pointing at max.
继续前进,我们看到:
bgt $t0, $t5, swapmax
您一定已经猜到,这是不正确的。原因:您正在将“地址”与值进行比较。 “地址”在 $t5 中,“值”在 $t0 中。如果你想获得$t5里面的值,你必须先加载它。也许使用另一个寄存器:
lw $t3, ($t5)
#OR
lw $t3, max # same thing, $t5 is pointing at 'max'
这些是明显的错误。可能有逻辑错误,但这是你的代码和你的程序,所以我会把它留给你根据需要修改你的逻辑
What does this error mean?
0x800000180是内核异常处理程序的地址。
这是因为您的代码出现异常。
您的模拟器似乎没有安装异常处理程序,因此在尝试 运行 异常处理程序时出现另一个异常。
要查看代码中的哪条指令触发了双重异常,单步执行代码直到它转到 0x800000180,然后从那里返回一条指令。它几乎肯定是加载或存储指令,为其内存地址指定了错误的指针。
除此之外,还应注意@Wagar 的建议。
我写了一个程序,它接受一些数字的输入并循环遍历每个数字。如果当前数字大于我最后一个最大数字,那么它应该交换最大值。如果它在最后一个数字(在我的字符串的末尾),它应该退出。
我正在尝试调试并且我明白,我并不真正理解指针是如何工作的以及何时必须在我的寄存器周围使用括号。
代码如下:
.data
first: .word 5, 6, -128, -5, 260, 34, 3, 20, -1
last: .word 44
max: .space 4
.text
lw $t0, first
lw $t1, last
lw $t5, max
sw $t5, $t0
loop:
beq $t0, $t1, ex
addi $t0, $t0, 4
bgt $t0, $t5, swapmax
j loop
swapmax:
lw $t0, ($t5)
ex:
lw $t5, max
li $v0, 10
syscall
我在哪里需要括号,为什么?
程序编译成功,但出现错误:
attempt to execute non-instruction at 0x800000180
这个错误是什么意思?
什么是指针?
指针是指向内存位置的东西。我们使用指针将值放在内存位置。例如在 C:
int max;
int *ptr = &max;
*ptr = 22; // max = 22
在上面的示例中,ptr 指向内存位置 (max),我们通过取消引用它来通过 ptr
更改 max 的值。
如何在MIPS中正确使用它们?
要理解这一点,您需要了解指令语法以及每条指令采用的操作数。显然,我们无法在一个答案中完成所有说明,所以我只会向您展示一些,以便您了解:
lw register, memory_location
sw register, memory_location
la register, memory_location
lw
从内存中加载一个字到寄存器中。示例:
lw $t0, first
lw $t0, ($t5) # this is like, int t0 = *t5
sw
将 register 中的值存储到 memory location 中。示例:
sw $t0, max # max = t1
sw $t0, ($t5) # *t5 = t0
la
将内存位置的地址加载到寄存器中。
la $t5, max # int *t5 = &max
现在让我们看看您的代码中的错误。这里:
lw $t5, max
上面会将 max
的值加载到 $t5
中。您似乎创建了 max
来存储最大值。在这里加载它似乎毫无意义,因为它甚至不包含任何内容。您想使用 la
:
la $t5, max #load address of max variable into $t5
继续前进,我们看到这条指令:
sw $t5, $t0
这不会assemble。这将导致错误。 sw
第一个操作数(源)是寄存器,第二个操作数是“内存位置”,而不是寄存器。
sw register, memory_location
所以,如果你想存储一些东西,你会这样做:
sw $t5, ($t0) #store value inside $t5 at the 'address' inside $t0.
# Assume:
# $t5 = 23
# $t0 = 0x5555
# After executing this instruction, memory location 0x5555 would have value 23 in it
这只是解释。在上面的代码中,您分配了 $t0 = first
。它甚至没有指向内存位置!但是,如果您执行 la $t5, max
.
所以,我假设你想做:
sw $t0, ($t5)
# After executing this, 'max' == $t0 because $t5 is pointing at max.
继续前进,我们看到:
bgt $t0, $t5, swapmax
您一定已经猜到,这是不正确的。原因:您正在将“地址”与值进行比较。 “地址”在 $t5 中,“值”在 $t0 中。如果你想获得$t5里面的值,你必须先加载它。也许使用另一个寄存器:
lw $t3, ($t5)
#OR
lw $t3, max # same thing, $t5 is pointing at 'max'
这些是明显的错误。可能有逻辑错误,但这是你的代码和你的程序,所以我会把它留给你根据需要修改你的逻辑
What does this error mean?
0x800000180是内核异常处理程序的地址。
这是因为您的代码出现异常。
您的模拟器似乎没有安装异常处理程序,因此在尝试 运行 异常处理程序时出现另一个异常。
要查看代码中的哪条指令触发了双重异常,单步执行代码直到它转到 0x800000180,然后从那里返回一条指令。它几乎肯定是加载或存储指令,为其内存地址指定了错误的指针。
除此之外,还应注意@Wagar 的建议。