首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将C语言转换为MIPS汇编语言

将C语言转换为MIPS汇编语言
EN

Stack Overflow用户
提问于 2021-06-04 22:42:26
回答 1查看 171关注 0票数 0

我想把c代码转换成MIPS,它可以在QTSpim上运行。例如:转换

代码语言:javascript
复制
#include<stdio.h>

int main() {
   printf("Hello, World!");
   return 0;
}

转到

代码语言:javascript
复制
.data
msg:   .asciiz "Hello World"
    .extern foobar 4

        .text
        .globl main
main:   li $v0, 4       # syscall 4 (print_str)
        la $a0, msg     # argument: string
        syscall         # print the string
        lw $t1, foobar
        
        jr $ra          # retrun to caller

我在我的苹果电脑上试用了一下gcc的-S helloWorld.c,然后我得到了如下的helloWorld.s:

代码语言:javascript
复制
.section    __TEXT,__text,regular,pure_instructions
    .build_version macos, 11, 0 sdk_version 11, 3
    .globl  _main                           ## -- Begin function main
    .p2align    4, 0x90
_main:                                  ## @main
    .cfi_startproc
## %bb.0:
    pushq   %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset %rbp, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register %rbp
    subq    $16, %rsp
    movl    $0, -4(%rbp)
    leaq    L_.str(%rip), %rdi
    movb    $0, %al
    callq   _printf
    xorl    %ecx, %ecx
    movl    %eax, -8(%rbp)                  ## 4-byte Spill
    movl    %ecx, %eax
    addq    $16, %rsp
    popq    %rbp
    retq
    .cfi_endproc
                                        ## -- End function
    .section    __TEXT,__cstring,cstring_literals
L_.str:                                 ## @.str
    .asciz  "Hello, World!"

.subsections_via_symbols

我已经搜索了一些,但没有明确的答案。我对MIPS很陌生,因为我发现有很多MIPS的汇编语言?任何解释或解决方案都将不胜感激。提前谢谢。

EN

回答 1

Stack Overflow用户

发布于 2021-06-04 22:52:53

流行的模拟器MARS和QTSpim都有自己的环境,也就是说,它们没有printfgetChar

相反,它们使用syscall进行I/O。syscall不是一个完整的编程环境,所以虽然它们可以做printf可以做的一些事情,但它们没有很多特性(例如,sprintf的特性完全缺失)。

以下是MARS中可用的syscall的文档(QTSPim支持第一组syscall,但不支持编号较高的syscall)。

http://courses.missouristate.edu/kenvollmar/mars/help/syscallhelp.html

要将printf语句转换为syscall形式,我们需要进行一些分解:

代码语言:javascript
复制
printf ( "hello %d\n", 10 ); 

会变成三个不同的syscall:

  1. 打印"hello“-使用syscall #4 (打印字符串)
  2. print 10 -使用syscall #1 (打印字符"\n”-使用syscall #4 (打印字符串),或syscall #11 (打印字符)

接下来你需要理解的是,系统调用本身有点像函数调用,所以我们需要理解参数传递。系统调用在$v0中接受一个函数代码,该代码说明要执行什么操作。每个函数都解释$a0、$a1等的值。根据上面链接中的规范。

为了传递参数,需要将值放置到寄存器中,但是将值放置到寄存器中的顺序是任意的-因此,只要$v0的值为4,并且$a0在内存中有一个指向字符串的指针,那么syscall指令就会打印该字符串。

我不知道任何编译器会自动将printf语句转换成MARS/QTSpim所需的形式。然而,可用的编译器(例如,godbolt.org有几个MIPS编译器可用)通常很好地显示非I/O C语句和表达式的汇编翻译(尽管它们的输出对于模拟器想要的东西来说是嘈杂的)。

模拟器的编程通常被简化。局部变量,特别是数组,通常作为全局变量来完成,因为在堆栈上创建数组需要额外的工作和对堆栈处理和堆栈偏移的理解,而全局变量很容易用名称来声明。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67839233

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档