【问题标题】:How to retrieve and print characters from even and odd indexes of a user inputted string in MIPS?如何从 MIPS 中用户输入字符串的偶数和奇数索引中检索和打印字符?
【发布时间】:2021-03-01 13:04:28
【问题描述】:

我是 MIPS 编码的新手(初学者),这是我从手册中发现的一个练习题。

我尽力为我的用户输入的字符串分配一个堆内存,这样我就可以遍历我的字符串的索引,但我无法弄清楚或继续前进。

有人可以解释并指导我如何从 evenodd 索引中检索打印字符用户使用 MARS 在 MIPS 中输入的字符串?

我在下面发布原始问题以及我尝试的代码。


编写一个 MIPS 程序,提示用户输入一个 16 的字符串 称为msg 的字符。然后使用以下代码实现 循环如下:

for(int j = 0; j < 2; j++) {
    for(int i = 0; i < 8; i++) {
        print(msg[(i * 2) + j]);    
    }
}

样本输出:

用户输入:"Iamhurtverybadly"

输出:"Imuteyalahrvrbdy"

这是我写到现在的:

        .data
Ask:    .asciiz "Sample Input: \n" 
Answer: .asciiz "Sample Output: \n"

        .text
        li $v0,9  #allocating heap memory
        syscall
        move $s1,$v0
        #print prompt for string,reading and storing string
        li $v0,4
        la $a0,Ask
        syscall
        li $v0, 8 
        la  $a0, 0($s1)
        move $a1,$s0
        syscall
        li $t0,0 #i=0
        li $t1,0 #j=0
        li $t2,2
        li $t3,8
loop:
        lb $t0,0($s1)
        bge $t0,$t2,loop2
        bge $t1,$t3,loop3
        sll $t0,$t0,1
        add $t4,$t0,$t1
        addi $t1,$t1,1
        j loop
loop3:
        addi $t0,$t0,1
        j loop
loop2:
        li $v0, 4
        la $a0, Answer #display result
        syscall
        li $v0,10
        syscall

【问题讨论】:

  • 请原谅我在循环中的代码格式

标签: assembly mips mips32


【解决方案1】:

让我们为您的程序集编写 C 代码:

for ( int i = 0, j = 0; i < 2; j++ ) {
    if ( j < 8 ) 
        i++;
    i <<= 1;
    int k = i + j;
}
print("Sample Output: \n");
exit();

这行不通,是吗?您只有一个循环(但有两个循环控制变量)。这不遵循原始代码的模型,它有 2 个循环,它们是嵌套的,一个完全在另一个中。此外,您通过在循环内加倍修改 i 变量。


首先,让我们一步一步回顾循环翻译:

for ( int j = 0; j < 2; j++ ) {
    ...                              // body of for loop
}

将for循环改为while循环:

int j = 0;
while ( j < 2 ) {                    // loop top & test
    ...                              // body of loop
    j++;                             // loop control resumes after body
}

将while循环改成if-goto-label样式的汇编:

    int j = 0;
loop1:                               // loop top
    if ( j >= 2 ) goto loop1Done;    // loop test
    ...                              // body of loop
    j++;                             // loop control
    goto loop1;                      // continue looping
loop1Done:                           // loop done, on to next statement after

现在,我们来做嵌套循环:

for ( int j = 0; j < 2; j++ ) {      // loop1
    for ( int i = 0; i < 8; i++ ) {  // loop2 (also body of loop1)
        print ( msg [ i*2+j ] );     // body of loop2
    }
}
exit();

将 for 循环改为 while 循环:

int j = 0;
while ( j < 2 ) {
                                     // for loop2 initialization
    int i = 0;                       // <<---- note where i=0 is: inside the outer loop
    while ( i < 8 ) {                // while loop2 top & test
        print ( msg [ i*2+j ] );     // body of loop2
        i++;                         // loop2 control
    }
    j++;                             // loop1 control
}
exit();

嵌套的控制结构应该相互独立地翻译。如果一个控制结构嵌套在 C 中的另一个中,那么它应该完全嵌入到另一个汇编语言的翻译中。

将while循环改成if-goto-label样式的汇编:

    int j = 0;
loop1:
    if ( j >= 2 ) goto loop1Done;

                                      // inner for loop2 starts here with initialization
    int i = 0;                        // <<---- note where i=0 is: inside the outer loop

loop2:                                // while loop2 starts here
    if ( i >= 8 ) goto loop2Done;
    print ( msg [ i*2+j ] );          // body of loop2
    i++;                              // loop2 resumes
    goto loop2;
loop2Done:                            // end of loop2

    j++;                              // loop1 resumes
    goto loop1;
loop1Done:                            // end of loop1

    exit();

你能在上面看到外循环和内循环是如何在 C 中完全相关的吗:内循环 (2) 完全嵌套在外循环 (1) 中。

上面的内容可以很容易地翻译成汇编语言,所以我将把它作为练习留给读者。只是不要在执行i*2+j 时修改ij — 将它们计算到其他未使用的寄存器中。

【讨论】:

  • 明白。我将尝试使用 MARS 工具。谢谢埃里克!
猜你喜欢
  • 2017-06-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-23
  • 1970-01-01
  • 2015-12-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多