【问题标题】:Character Comparison from C to MIPS32从 C 到 MIPS32 的字符比较
【发布时间】:2019-02-12 06:18:53
【问题描述】:

我得到了两个需要转换为 MIPS32 指令的 C 函数。

我是编程新手。到目前为止,我试图了解 C 中实际发生的情况,然后使用 MIPS 指令将 C 代码翻译成汇编语言。我主要使用跳转指令来跳转代码的不同部分。我确信可能有更好的方法来使用寄存器来使代码简洁,但在这一点上,我只是试图让我的概念正确并理解字符串操作。之后我将致力于优化代码。

C 代码:

char firstmatch(char *s1, char *s2) {
    char *temp;
    temp = s1;
    do {
        if (strchr(s2, *temp) != 0)
            return temp;
        temp++;
        } while (*temp != 0);
    return 0;
    }

char *strchr(register const char *s, int c) {
    do {
        if (*s == c) {
            return (char*)s;
       }
    } while (*s++);
    return (0);
   }

MIPS 代码:

.data

str1: .asciiz "hello \n"    #String 1
str2: .asciiz "meh \n"      #String 2

char_found: .asciiz " is the first character in string s1 that is also in s2 \n"     
char_not_found: .asciiz "No character match between the two strings \n" 


.text

main:

    la $a0, str1    #Loading address of string 1 into register $a0
    la $a1, str2    #Loading address of string 2 into register $a1  


firstmatch:

    move $t0, $a0   #Passing address of str1 from $a0 to $t0        
    move $t1, $a1   #Passing address of str1 from $a1 to $t1
    addi $t2,$t0,0  #Using $t2 register for the temp variable


Load_Bytes:

    lb $t4, 0($t1)  #Loading the first character of str2 
    lb $t3, 0($t2)  #Loading the first character of str1 


strchr:         
    beq   $t4,$t3,Label_1   #Checking for character match. 
    j Label_2       #No match, go to Label_2


Label_1:    #Label to Print character as well as char_found string 
    li $v0, 4           
    la $s0, ($t4)
    syscall
    la $t5, char_found
    syscall 


Label_2:

    addi $t2, $t2, 1    #Incrementing temp by 1
    lb $t6, 0($t2)      #Using t6 to check for NULL character
    beqz $t6, Label_4   #Checking if value at $t2 is 0.
    j Load_Bytes

Label_3:            #Label to print when no character match

    li $v0, 4           
    la $t5, char_not_found
    syscall 


Label_4:

    addi $t1, $t1, 1    #Increment str2 byte by 1 after string 1 iteration reaches the NULLL character
    lb $t7, 0($t1)      #Using t7 to check for NULL character
    beqz $t7, Label_3   #Checking if value at str 2($t1) is 0
    addi $t2, $t0, 0    #Re-initialize string 1
    j Load_Bytes

目前,我的代码一直在无休止地运行并打印字符串 1。我怀疑我没有理解正确加载地址和字节的概念,或者存在不断重复程序的跳转条件。任何帮助将不胜感激。

【问题讨论】:

  • 问:你有真正的 MIPS CPU 可以使用吗?问:它是否在具有 C 编译器和 MIPS 汇编器的 MIPS 工作站上?建议:如果您的 C 编译器能够转储 MIPS 程序集(例如,gcc -s myfile.c),那可能是“最简单”的方法。
  • 哪些代码在无休止地运行,我假设您的意思是 MIPS 代码,但我只是想澄清一下,因为提供的 C 代码不足以单独运行。
  • @Bwebb 这是在 MARS 模拟器上无休止地运行的 MIPS 代码。请参阅我上面对保罗问题的评论,以更好地了解问题可能是什么。谢谢
  • @paulsm4 我正在使用 MARS 4.5 模拟器来运行 MIPS 代码。我从密苏里州立大学的网站上找到了模拟器。链接是:courses.missouristate.edu/KenVollmar/mars/download.htm 程序无限运行并打印出字符串 1。
  • 你期望在颂歌之后发生什么,例如Label_1 到达最终的系统调用?它将继续在 Label_2 中的代码,不可避免地跳转到 Label_4 或 Load_Bytes。没有迹象表明程序在任何地方调用了退出系统调用 (10)。系统调用的参数应该在寄存器$a<N> 中,而不是在像$t5 这样的临时寄存器中

标签: c cpu-registers mips32


【解决方案1】:
.data

str1: .asciiz "HeLlo"           #String 1
str2: .asciiz "mEadow"          #String 2

    char_found: .asciiz " is the first character in string s1 that is also in s2 \n"     #To be printed when character is found
    char_not_found: .asciiz "No character match between the two strings \n"          #To be printed if there is no match        

.text

    main:

        la $a1,str1             #Loading address of string 1 into register $a1
        la $a2,str2             #Loading address of string 2 into register $a2

        move $t0,$a1            #Passing address of str1 from $a1 to temp register $t0      
        move $t1,$a2            #Passing address of str1 from $a2 to temp register $t1
        addi $t2,$t0,0          #Using $t2 register for the temp variable in the code


    Load_Bytes:

        lb $t4, 0($t1)          #Loading the first character of str2 from memory address $t1 to $t4
        lb $t3, 0($t2)          #Loading the first character of str1 from memory address $t2 to $t3


    strchr:         
        beq $t3,$t4,Label_1     #Checking for character match. If yes, going to Label_1. If not, continue
        jal firstmatch

        addi $t1, $t1, 1        #Increment str2 byte by 1 after string 1 iteration reaches the NULLL character
        lb $t7, 0($t1)          #Using t7 as temporary register to check for NULL character in the next step
        beqz $t7, Label_2       #Checking if value at string 2($t1) is 0. If yes, go to Label_5
        addi $t2, $t0, 0        #Re-initialize string 1 to start the compare loop again
        j Load_Bytes            


    firstmatch:

        addi $t2, $t2, 1        #Incrementing temp by 1
        lb $t6, 0($t2)          #Using t6 as temporary register to check for NULL character in the next step
        bnez $t6, Load_Bytes        #Checking if value at $t2 is 0. If yes, going to Label_2. If not, continue and iterate the loop 
        jr $ra  


    Label_1:                #Label to Print character as well as char_found string above simultaneously

        la $a0,($t4)
        li $v0, 11          
        syscall 

        la $a0, char_found
        li $v0, 4
        syscall

        li $v0,10
        syscall     

    Label_2:                #Label to print when no character match is found

        la $a0, char_not_found
        li $v0, 4           
        syscall 

        li $v0, 10
        syscall

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-05-09
    • 1970-01-01
    • 2021-11-19
    • 2016-02-08
    • 2013-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多