MIPS阵列更新 [英] MIPS array update

查看:113
本文介绍了MIPS阵列更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在将C代码转换为MIPS代码时遇到问题.原始的C代码如下:

I have a problem in converting my C code to MIPS code. The original C code is below:

int A[4];
int i;
int diff;
for(i=0; i<3; i++){
   diff = A[i+1] - A[i];
   if (diff > 0)
     A[i] = 5*A[i];
   else
     A[i+1] = -5*A[i];
}

以下是我的MIPS代码:

And here is my MIPS Code below:

### MIPS PROJECT PART 1: ARRAY USING FOR LOOPS  

.data
    # allocate 16 bytes memory for 4 integer array 
    A: .space 16


.text 
    # Store array values in registers
    addi $s0,$zero,2
    addi $s1,$zero,4
    addi $s2,$zero,6
    addi $s3,$zero,8

    # Index = $t0
    addi $t0,$zero,0
    # Store the first index and then store others by increasing $t0 by 4 bytes
    sw $s0,A($t0)
        addi $t0,$t0,4
    sw $s1,A($t0)
        addi $t0,$t0,4
    sw $s2,A($t0)
        addi $t0,$t0,4
    sw $s3,A($t0)


    main:   
        li $s4,0    # counter i = $s4
        li $t2,3    # constant $t2
    loop:
        beq $s4, $t2, end # if t1 == 3 we are done  
        # diff = A[i+1] - A[i]
        lw $t3,A($zero) # $t3 =  A[i]
        addi $t6, $zero,4 # next element A[i+1]
        lw $t4,A($t6) # $t4 = A[i+1]
        sub $t5,$t4,$t3 # dif = $t5 = A[i+1] - A[i]


        # if (diff > 0)
        bltz $t5, Else
            # A[i] = 5*A[i]
            add $t5,$zero,$t5
            add $t5,$zero,$t5
            add $t5,$zero,$t5
            add $t5,$zero,$t5
            sw $t5 A($zero)

        Else:
            # else  A[i+1] = -5 * A[i];

        addi $zero, $zero,4           #next element A[i+1]
        #Loop body
        addi $s4, $s4, 1 # add 1 to $s4
        j loop # jump back to the top
    end:
        li $v0,10
        syscall

问题是程序不会更新数组值.另外,我被限制使用乘法命令(mult或mull),这就是为什么我只想在控制语句中将其添加5次.

The thing is that program does not update array values. Additionally I am restricted to use multiplication commands (mult or mull), that is why I am trying just to add it 5 times in control statement.

推荐答案

您的程序存在一些错误,并且不完整.我创建了两个版本.一种带有错误注释,另一种经过重构.请原谅免费的样式清理.

Your program has some bugs and is incomplete. I've created two versions. One with annotations for the bugs and a refactored one. Please pardon the gratuitous style cleanup.

这是您的带有注释的asm程序:

Here's your asm program with annotations:

### MIPS PROJECT PART 1: ARRAY USING FOR LOOPS

    .data
A:          .space      16
    # allocate 16 bytes memory for 4 integer array

    .text
    # Store array values in registers
    addi    $s0,$zero,2
    addi    $s1,$zero,4
    addi    $s2,$zero,6
    addi    $s3,$zero,8

    # Index = $t0
    addi    $t0,$zero,0
    # Store the first index and then store others by increasing $t0 by 4 bytes
    sw      $s0,A($t0)
    addi    $t0,$t0,4
    sw      $s1,A($t0)
    addi    $t0,$t0,4
    sw      $s2,A($t0)
    addi    $t0,$t0,4
    sw      $s3,A($t0)

# NOTE/BUG: this should go after the .text as the above code may be skipped
main:
    li      $s4,0                   # counter i = $s4
    li      $t2,3                   # constant $t2

loop:
    beq     $s4,$t2,end             # if t1 == 3 we are done
    # diff = A[i+1] - A[i]

# NOTE/BUG: this always loads from A[0]
    lw      $t3,A($zero)            # $t3 =  A[i]

# NOTE/BUG: this always loads from A[1]
    addi    $t6,$zero,4             # next element A[i+1]
    lw      $t4,A($t6)              # $t4 = A[i+1]

    sub     $t5,$t4,$t3             # dif = $t5 = A[i+1] - A[i]

    # if (diff > 0)
    bltz    $t5,Else

# NOTE/BUG: this is _not_ A[i] but is diff
# NOTE/BUG: this is _not_ 5* but higher (see below)
    # A[i] = 5*A[i]
    add     $t5,$zero,$t5           # diff*2
    add     $t5,$zero,$t5           # diff*4
    add     $t5,$zero,$t5           # diff*8
    add     $t5,$zero,$t5           # diff*16

# NOTE/BUG: this always stores to A[0]
    sw      $t5,A($zero)

# NOTE/BUG: this falls through to the else case

Else:
    # else  A[i+1] = -5 * A[i];

# NOTE/BUG: this is just a nop because a $zero as destination reg does
# nothing
    addi    $zero,$zero,4           # next element A[i+1]

    # Loop body
    addi    $s4,$s4,1               # add 1 to $s4

# NOTE/BUG: this stores nothing
    j       loop                    # jump back to the top

end:
    li      $v0,10
    syscall


我稍微重写了C代码以使汇编更容易:


I rewrote the C code slightly to make the asm easier:

int A[4] = { 2, 4, 6, 8 };

void
calc(int *arr,int cnt)
{
    int tmp;
    int diff;
    int *endp;

    endp = &arr[cnt];

    for (;  arr < endp;  arr += 1) {
        tmp = arr[0];
        diff = arr[1] - tmp;

        if (diff > 0) {
            tmp = 5 * tmp;
            arr[0] = tmp;
        }
        else {
            tmp = -5 * tmp;
            arr[1] = tmp;
        }
    }
}


这是重构的asm代码:


Here's the refactored asm code:

### MIPS PROJECT PART 1: ARRAY USING FOR LOOPS

    .data
# allocate 16 bytes memory for 4 integer array
A:  .word   2,4,6,8

space:  .asciiz " "
nl:     .asciiz "\n"

    .text
main:
    la      $a0,A
    li      $a1,4
    jal     print

    la      $a0,A
    li      $a1,3
    jal     calc

    la      $a0,A
    li      $a1,4
    jal     print

    li      $v0,10
    syscall

# calc -- calculate results
#
# arguments:
#   a0 -- pointer to array
#   a1 -- count of array
calc:
    # get endp
    sll     $a1,$a1,2               # convert int count to byte count
    addu    $a1,$a1,$a0             # add in array base
    j       calc_start              # start loop

calc_loop:
    lw      $t3,0($a0)              # tmp = A[i]
    lw      $t4,4($a0)              # A[i + 1]
    sub     $t5,$t4,$t3             # get diff
    bltz    $t5,calc_neg            # < 0

    add     $t5,$t3,$t3             # tmp = A[i]*2
    add     $t5,$t5,$t5             # tmp = A[i]*4
    add     $t5,$t5,$t3             # tmp = A[i]*5
    sw      $t5,0($a0)
    b       calc_next

calc_neg:
    neg     $t3,$t3
    add     $t5,$t3,$t3             # tmp = A[i]*2
    add     $t5,$t5,$t5             # tmp = A[i]*4
    add     $t5,$t5,$t3             # tmp = A[i]*5
    sw      $t5,4($a0)

calc_next:
    addiu   $a0,$a0,4
calc_start:
    bne     $a0,$a1,calc_loop       # more to do? if yes, fly
    jr      $ra                     # return

# print -- print results
#
# arguments:
#   a0 -- pointer to array
#   a1 -- count of array
#
# temporaries:
#   a2 -- array pointer
#   a3 -- array count
print:
    move    $a2,$a0
    move    $a3,$a1
    j       print_next

print_loop:
    li      $v0,4
    la      $a0,space
    syscall

    li      $v0,1
    lw      $a0,0($a2)              # get current value
    syscall

    addiu   $a2,$a2,4
    addi    $a3,$a3,-1
print_next:
    bnez    $a3,print_loop

    li      $v0,4
    la      $a0,nl
    syscall

    jr      $ra                     # return

这篇关于MIPS阵列更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆