MIPS Assembly如何将值存储到数组中?

发布于 2025-01-13 23:51:35 字数 768 浏览 2 评论 0原文

我正在尝试创建一个程序,可以在数组中存储最多 8 个值,然后比较所有这些值以找到最小的数字。由于某种原因,我的循环每次都会覆盖数组中的第一个位置。这就是我所拥有的。然后我在循环中将 4 添加到 $t1 中,因此一旦返回,它应该将下一个整数存储在之后的空间中。我不明白我在这里做错了什么?

    .data
myArray: .space 32
Msg1: .asciiz "Enter an integer: "


.text


main:
 # Print Message
 li $v0, 4
 la $a0, Msg1
 syscall

 # Prompt the user to enter an integer
 li $v0, 5
 syscall

 # Store the first integer in $t0
 move $t0, $v0
 
 # Declare $t1 for the array position that the integer will be stored at
 addi $t1, $zero, 0
 
 # Store the integer in the array
 sw $t0, myArray($t1)
 
 #Add 4 to $t1 so store the next value in the next array position 
 addi $t1, $zero, 4
 
 beq $t0, $zero, Exit
 
 j main



Exit:
     # Declare an exit to the program
     li $v0, 10
     syscall

I am trying to create a program where I can store up to 8 values in an array and then compare all these values to find the smallest number. For some reason my loop overwrites the first position in the array every time. Here's what I have. I then add 4 to $t1 on the loop so once it goes back around it should store the next integer in the space after that. I don't see what I'm doing wrong here?

    .data
myArray: .space 32
Msg1: .asciiz "Enter an integer: "


.text


main:
 # Print Message
 li $v0, 4
 la $a0, Msg1
 syscall

 # Prompt the user to enter an integer
 li $v0, 5
 syscall

 # Store the first integer in $t0
 move $t0, $v0
 
 # Declare $t1 for the array position that the integer will be stored at
 addi $t1, $zero, 0
 
 # Store the integer in the array
 sw $t0, myArray($t1)
 
 #Add 4 to $t1 so store the next value in the next array position 
 addi $t1, $zero, 4
 
 beq $t0, $zero, Exit
 
 j main



Exit:
     # Declare an exit to the program
     li $v0, 10
     syscall

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

溺渁∝ 2025-01-20 23:51:35

首先,让我们从 C 语言的工作算法开始:

int a [] = { /* array elements */ };
int n = /* count of number of elements */;
...

int currMin = 0;
for ( int i = 0; i < n; i++ ) {
    int next = a[i];       // next array element to check
    if ( next < currMin )  // is it smaller than what we've seen so far?
        currMin = next;    // yes: capture new min value
}
// on exit from the loop currMin holds the min value

好的,现在我们将进行一些简单的逻辑转换,以将其转换为汇编语言。首先,我们删除 for 循环,转而使用稍微简单的 while 循环结构。

int currMin = 0;
int i = 0;
while ( i < n ) {
    int next = a[i];       // next array element to check
    if ( next < currMin )  // is it smaller than what we've seen so far?
        currMin = next;    // yes: capture new min value
    i++;
}
// on exit from the loop currMin holds the min value

接下来,我们将 while 循环转换为程序集的 if-goto-label。 (我们可以先执行 if-then;我们转换的顺序并不重要。)

    int currMin = 0;
    int i = 0;
loop1:
    if ( i >= n ) goto endLoop1;
    int next = a[i];       // next array element to check
    if ( next < currMin )  // is it smaller than what we've seen so far?
        currMin = next;    // yes: capture new min value
    i++;
    goto loop1;
endLoop1:
// on exit from the loop currMin holds the min value

接下来,我们将执行 if-then 语句。我们本来可以先这样做,但这不会改变分析或结果。

    int currMin = 0;
    int i = 0;
loop1:
    if ( i >= n ) goto endLoop1;
    int next = a[i];       // next array element to check
    if ( next >= currMin ) goto endIf1;
    currMin = next;    // yes: capture new min value
endIf1:
    i++;
    goto loop1;
endLoop1:

接下来我们将把它转化为汇编语言。

首先,将变量分配给物理存储,这里最好的选择是寄存器。思维导图:

$a0 array a
$a1 element count n

$v0 currMin, the result

$t0 loop control variable i, also used as index
$t1 temporary variable "next"

第二,按照上面最后一个翻译代码:

    li $v0, 0   # currMin = 0
    li $t0, 0   # i = 0

loop1:
    bge $t0, $a1, endLoop1

    # array reference, variable index: a[i], capture in "next"/$t1
    sll $t9, $t0, 2
    add $t9, $a0, $t9
    lw $t1, 0($t9)

    # the if-then inside the loop body    
    bge $t1, $v0, endIf1
    move $v0, $t1         # capture newly seen lowest value
endIf1:

    # finish the rest of the while loop, having the for-loop i++ here
    addi $t0, $t0, 1
    j loop1
endLoop1:

剩下的就是在其周围放置一些开始和结束代码,假设寄存器编号匹配。

起始代码会将数组的地址放入 $a0 中,并将元素计数放入 $a1 中。当然可以使用不同的寄存器,并进行适当的修改。

结束代码应该期望 $v0 中的结果,打印或以其他方式。

起始代码将完全在此代码之前,结束代码完全在此代码之后。


是的,有几个步骤 - 但每个步骤都是相对简单且符合逻辑的转换。逻辑转换可以翻译 C 代码,首先保留 C 代码,然后进行简化,以便轻松直接进行汇编。

  1. 删除 for 循环,改用 while 循环。
  2. 将所有控制结构改为if-goto-label
    每个控制结构(if、while)一次可以更改一个,留在 C 中,并不断检查代码是否继续在 C 中工作!控制结构转换的顺序并不重要(从内到外,从外到内)。
  3. 将简化的 C 代码转换为汇编代码:
    一个。将C的逻辑变量映射到机器代码的物理存储
    b.转换语句 &从 C 语言到汇编语言的表达式

First, let's start with a working algorithm in C:

int a [] = { /* array elements */ };
int n = /* count of number of elements */;
...

int currMin = 0;
for ( int i = 0; i < n; i++ ) {
    int next = a[i];       // next array element to check
    if ( next < currMin )  // is it smaller than what we've seen so far?
        currMin = next;    // yes: capture new min value
}
// on exit from the loop currMin holds the min value

Ok, now we'll make some simple logical transformations on the way to taking this to assembly language.  First, we remove the for loop in favor of the slightly simpler while loop construct.

int currMin = 0;
int i = 0;
while ( i < n ) {
    int next = a[i];       // next array element to check
    if ( next < currMin )  // is it smaller than what we've seen so far?
        currMin = next;    // yes: capture new min value
    i++;
}
// on exit from the loop currMin holds the min value

Next, we'll transform the while loop into assembly's if-goto-label.  (We could work the if-then first instead; the order we transform doesn't matter.)

    int currMin = 0;
    int i = 0;
loop1:
    if ( i >= n ) goto endLoop1;
    int next = a[i];       // next array element to check
    if ( next < currMin )  // is it smaller than what we've seen so far?
        currMin = next;    // yes: capture new min value
    i++;
    goto loop1;
endLoop1:
// on exit from the loop currMin holds the min value

Next, we'll do the if-then statement.  We could have done it first, that wouldn't change the analysis or results.

    int currMin = 0;
    int i = 0;
loop1:
    if ( i >= n ) goto endLoop1;
    int next = a[i];       // next array element to check
    if ( next >= currMin ) goto endIf1;
    currMin = next;    // yes: capture new min value
endIf1:
    i++;
    goto loop1;
endLoop1:

Next we'll take this to assembly language.

First, assign variables to physical storage, here good choice is registers.  Mental map:

$a0 array a
$a1 element count n

$v0 currMin, the result

$t0 loop control variable i, also used as index
$t1 temporary variable "next"

Second, translate code as per the last above:

    li $v0, 0   # currMin = 0
    li $t0, 0   # i = 0

loop1:
    bge $t0, $a1, endLoop1

    # array reference, variable index: a[i], capture in "next"/$t1
    sll $t9, $t0, 2
    add $t9, $a0, $t9
    lw $t1, 0($t9)

    # the if-then inside the loop body    
    bge $t1, $v0, endIf1
    move $v0, $t1         # capture newly seen lowest value
endIf1:

    # finish the rest of the while loop, having the for-loop i++ here
    addi $t0, $t0, 1
    j loop1
endLoop1:

All that's left is to put some starting and ending code around that, assuming the register numbers match up.

The starting code for this would put the address of the array into $a0, and the count of elements into $a1.  Could use different registers of course, with appropriate modifications.

The ending code should expect the result in $v0, to print or otherwise.

The starting code would be entirely before this code, and the ending code entirely after.


Yes, there are a few steps — but each one is a relatively simple and logical transformation.  Logical transformations enable translating the C code, first staying in C but simplifying to make it easy to go right to assembly.

  1. Remove for loops in favor of while loops.
  2. Change all control structures into if-goto-label
    Each control structure (if, while) can be changed one at a time, stay in C, and keep checking that the code continues to work in C!  Order of control structure transformations doesn't matter (inside out, outside in).
  3. Translate simplified C code into assembly:
    a. Map logical variables of C into physical storage of machine code
    b. Convert statements & expressions from C into assembly language
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文