【问题标题】:inserting an integer at the beginning of an array MIPS在数组 MIPS 的开头插入一个整数
【发布时间】:2017-06-24 04:41:56
【问题描述】:

在数组开头插入整数的方法是什么?

例子:

注册 $s0 = 4(数组中的元素数)

寄存器$s1 = 0x10040000(数组开头的地址)

0x10040000 10
0x10040004 20
0x10040008 30
0x1000400C 40

我想在 0x10040000 处插入一个 int,比如 5 并将所有内容向下移动:

0x10040000 5
0x10040004 10
0x10040008 20
0x1000400C 30
0x10004010 40

我能够做到的一种方法是在数组之前的地址处插入 5,但我想做的是在数组的开头插入 5 并将其他所有内容向下移动

【问题讨论】:

  • 好吧,如果你不再把它想象成一个数组,而只看两个“内存图像”,就很明显需要做什么了。您需要将内存内容向上移动 4 个字节(0x10040000 中的 4 个字),然后将5 写入0x10040000。这种memmove,要以最佳方式完成,通常是非常特定于CPU的(不确定MIPS),但是当性能不是问题时,你只需要i=4; while (i--) array[i+1] = array[i];(从数组端开始,所以你不要' t 用移动的值覆盖原始值)。
  • 顺便说一句,这就是为什么 C++ vector<> 被认为插入“慢”的原因,因为您总是需要移动数组的剩余部分以在连续存储中创建空槽,但是计算机喜欢使用连续打包好的数据结构,因此这种插入惩罚通常会在进一步处理中迅速恢复,所以不要低估vector<> 结构的力量,而不是猜测使用分析来找到真正的性能。 vector<> 类型的数据结构通常是初始版本的最佳开始。

标签: arrays assembly mips mips32


【解决方案1】:

您需要一个循环和一个临时寄存器 ($s0) 来移动值:

.data
N: .word 3
VET: .word 2, 3, 4, 5

.text
li $t1, 0 
lw $t0, N
sll $t0, $t0, 2
la $t2, $t0(VET)
srl $t0, $t0, 2
loop:
blt $t0, $t1 end_loop
lw $s0, ($t2) #load the number from i pos
sw $s0, 4($t2) #store the number in i+1 pos
addi $t2, $t2, -4 #i--
addi $t0, $t0, -1
j loop
end_loop:
li $s0, 1 #load value you want to store
sw $s0, VET #store value
lw $t0, N
add $t0, $t0, 1 
sw $t0, N #update value of N

现在1 的值位于向量的开头。 没有优化,只是为了让你理解程序背后的逻辑。希望这会有所帮助。

【讨论】:

    【解决方案2】:

    你需要一个内循环和一个外循环。

    .data
    Array: .word 3 5 1 90 21 11 2
    .text 
    la $a0,Array
    addi $a1,$zero,7 
    jal InsertSort
    
    li $v0,10
    syscall
    
    InserSort:
    addi $t0,$zero,1
    outerloop:
    beq $t0,$a1,finish
    
    sll $t4,$t0,2
    add $t4,$t4,$a0
    lw $t4,0($t4)
    
    addi $t1,$t0,-1
    innerloop:
    slt $t2,$t1,$zero
    bne $t2,$zero,GoOuter
    
    sll $t3,$t1,2
    add $t3,$t3,$a0
    lw t3,0($t3)
    slt $t5,$t3,$t4
    bne $t5,$zero,GoOuter
    
    addi $t6,$t1,1
    sll $t6,$t6,2
    add $t6,$t6,$a0
    sw $t3,0($t6)
    addi $t1,$t1,-1
    j innerloop
    
    GoOuter:
    
    addi $t8,$t1,1
    sll $t8,$t8,2
    add $t8,$t8,$a0
    sw $t4,0($t8)
    addi $t0,$t0,1
    j outerloop
    
    finish:
    jr $ra
    

    【讨论】:

    • 请为您的代码使用代码格式(三个反引号)。将指令相对于标签缩进一级也是一种很好的编码风格。将操作数缩进到一致的列也很好,因此不同长度的助记符不会使事情变得参差不齐。这样可以更容易地查看不同指令之间涉及哪些寄存器。此外,一个好的 Stack Overflow 答案将非常彻底地评论代码以解释它为什么/如何工作。
    • 这个问题不是问插入排序,而是问如何在指定位置进行一次插入。喜欢 C++ std::vector<int>::insert(pos, value) (en.cppreference.com/w/cpp/container/vector/insert)
    猜你喜欢
    • 1970-01-01
    • 2010-12-16
    • 2014-04-11
    • 2014-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多