【问题标题】:Can someone explain to me what happens at a certain part of this code? (MIPS/ASSEMBLY)有人可以向我解释这段代码的某个部分会发生什么吗? (MIPS/组装)
【发布时间】:2014-03-19 04:50:11
【问题描述】:

对不起,我一直在问我感觉很糟糕的问题。

  .data
.align 4
Table: .space 24
msg1: .asciiz "Please insert an integer: "
msg2: .asciiz " "
msg3: .asciiz "\nVector contents: "
.text
.globl main
main:

addi $s0,$zero,5
addi $t0,$zero,0
in:
li $v0,4
la $a0,msg1
syscall
li $v0,5
syscall
add $t1,$t0,$zero
sll $t1,$t0,2
add $t3,$v0,$zero
sw $t3,Table ( $t1 )
addi $t0,$t0,1
slt $t1,$s0,$t0
beq $t1,$zero,in

la $a0,Table
addi $a1,$s0,1 #a1=6
#call buble_sort
jal buble_sort

#print table
li $v0,4
la $a0,msg3
syscall
la $t0,Table
#s0=5
add $t1,$zero,$zero
printtable:
lw $a0,0($t0)
li $v0,1
syscall
li $v0,4
la $a0,msg2
syscall
addi $t0,$t0,4
addi $t1,$t1,1
slt $t2,$s0,$t1
beq $t2,$zero,printtable

li $v0,10
syscall

buble_sort:
#a0=address of table
#a1=sizeof table
add $t0,$zero,$zero #counter1( i )=0

loop1:
addi $t0,$t0,1 #i++
bgt $t0,$a1,endloop1 #if t0 < a1 break;

add $t1,$a1,$zero #counter2=size=6
loop2:

bge $t0,$t1,loop1 #j < = i

#slt $t3,$t1,$t0
#bne $t3,$zero,loop1

addi $t1,$t1,-1 #j--

mul $t4,$t1,4 #t4+a0=table[j]
addi $t3,$t4,-4 #t3+a0=table[j-1]
add $t7,$t4,$a0 #t7=table[j]
add $t8,$t3,$a0 #t8=table[j-1]
lw $t5,0($t7)
lw $t6,0($t8)

bgt $t5,$t6,loop2

#switch t5,t6
sw $t5,0($t8)
sw $t6,0($t7)
j loop2

endloop1:
jr $ra

这不是我的代码,我只是想了解某个地方发生了什么

几个问题.. ALIGN 和 .SPACE 有什么作用?你怎么知道你需要分配多少空间?

我了解大部分代码(至少我认为我了解)但我对 loop1 和 loop2 标签感到困惑。

主要问题: 我的问题是程序什么时候回到loop1?如果循环 1 的计数器从 1(来自 addi)开始,它需要达到 6 才能中断。什么时候调用它来增加 +1 因为在 loop2

bge $t0,$t1,loop1

除非 $t0 增加,否则这永远不会是真的? $t1 值是数组的值,即 6。 我看不到程序会回到 loop1 ......所以有人可以向我解释它是怎么做的吗?计数器必须以某种方式达到 6,因为程序运行良好。 (从小到大打印出排列整齐的数组)

【问题讨论】:

    标签: mips subroutine mars-simulator


    【解决方案1】:

    使用 MARS 模拟器(是的,我知道“模拟器”是多余的,一旦人们不再提及 ATM 机和 PIN 码,我就会修复它),.align 4 会将对齐设置为 16 的倍数( 2<sup>4</sup>)。例如,它将确保 Table 位于 16 字节边界上,例如 00004110fff0。对齐通常是因为如果n-byte 数据元素在n-byte 边界上对齐,则某些 CPU 工作得更快(如果违反对齐,有些甚至会引发硬件异常)但我不确定情况是否如此,因为16 的对齐方式相当“宽”。

    .space 24 只是分配了 24 个字节的空间,在本例中用于保存 Table 数据结构。

    根据$s0$t0 之间的交互,您的初始循环(输入数据)似乎有六个条目的限制。

    指令顺序:

    slt $t1,$s0,$t0
    beq $t1,$zero,in
    

    只要$s0 (= 5) 小于$t0,就会分支回到in,所以$t0 会从0 迭代到5(包括六项)。

    这个限制是您决定分配多少空间的方式(六个 32 位值将是 24 个字节)。


    那个循环工作。您声明:

    bge $t0,$t1,loop1 :除非$t0 增加,否则这永远不会成立?

    但事实上,这并不完全正确,如果您减少 $t1,它可能变为真的,你瞧,它在第三行代码 (non-':') 上下面:

    loop2:
    bge $t0,$t1,loop1 #j < = i
    :
    addi $t1,$t1,-1 #j--
    :
    j loop2
    

    从伪代码的角度来看,和这两个循环是一样的(就迭代次数而言):

    limit = 10, value = 0      limit = 10, value = 0
    while value < limit:       while value < limit:
        value = value + 1          limit = limit - 1
    

    【讨论】:

    • 我还是不明白你怎么知道你需要多少空间?我假设只使用你需要的空间而不是随机的高数字会更优化?
    • 输入数据的限制为6。或者至少代码要求输入数字6次。但是,如果我将空间更改为较小的数量,它会让我输入一个数字,它只是不会输出文本来询问我是否有意义。无论如何,感谢您的帮助 :D 它开始对我更有意义.. 现在我只是希望有人能回答我关于实际代码 +_+ 的问题。谢谢!
    • @Jpyo,这是因为,如果您为五个数字留出空间并输入/存储六个,第六个将覆盖 msg1,即内存中的下一个内容。
    • 天哪,哈哈。我不敢相信我没有看到它。我的意思是我看到了它,但我忽略了它,因为我一直在努力寻找 $t0 增加的地方,以至于我没有费心去检查 $t1 是否减少了,尽管我已经把它写在了我的论文 x_o 上!
    • 我倾向于只看一种可能性而忘记其他可能性,因此,我在编写代码时搞砸了很多,因为我看不到其他方法来处理它。谢谢!如果我能投票一百万次,我会的。
    猜你喜欢
    • 1970-01-01
    • 2011-08-20
    • 1970-01-01
    • 1970-01-01
    • 2011-05-31
    • 2015-02-04
    • 1970-01-01
    • 2011-02-28
    • 1970-01-01
    相关资源
    最近更新 更多