C语言如何转换成计算机底层的二进制语言(MIPS)

文章开头我只想问一个问题:写了很多代码,你不好奇代码在计算机底层是什么样的吗?

下面将一步一步探索这个过程。首先,大家要有个初步的认识,一次从左到右进行编译汇编。

高级语言(C语言)                                汇编语言                                                    二进制机器语言

int add(int a,int b){                           add: 
    int c;                                                    add   $a2,$a0,$a1  //c=a+b                      00000000100001010011000000100000 
    c = a + b;                  -->编译               add  $v0,$a2,$zero                -->汇编       00000000110000000001000000100000
    return c;                                               jr       $ra                                                   00000011111000000000000000001000
}

关于 $a2,$ra等寄存器,大家可以看看这篇博主的文章总结 MIPS 通用寄存器 。

首先大家要了解计算机的一个概念--过程意思是根据提供的参数执行一定任务的存储的子程序。说白了,就是上述C语言add函数里面的逻辑在CPU执行的过程。MIPS在为过程调用分配32个寄存器是遵循以下约定:

  • $a0~$a3:用于传递参数的4个参数寄存器。如上述的 $a0 即为 a,$a1即为b,由于参数寄存器还足够,因此 $a2即为c。
  • $v0~$v1:用于返回值的两个寄存器。
  • $ra:用于返回起始点的返回地址寄存器。如上述的 jr  $ra,意思是无条件跳转到寄存器所制定的地址。通俗地说,$ra是存储调用过程前的指令地址,执行完过程后,跳转到调用过程前的指令地址,继续做后续的计算。int a1 = add(1,2),执行完过程add的逻辑后, jr  $ra由回到a1继续计算。因为过程是可能由程序中多个点调用。即 int a2 = add(3,4);执行完 jr  $ra后回到a2继续计算。代码可以如下:

#include <stdio.h>

int add(int a,int b){
    int c;
    c = a + b;
    return c;
}

void main(){
    int a1 = add(1,2);
    int a2 = add(3,4);
}

综上所述,大家应该知道为啥$a0 即为 a,$a1即为b,$a2即为c了。接下来,我们继续,汇编语言怎么转换成二进制程序语言。想必大家都了解到,无论什么程序,最后在计算机底层都是 0 1 存在的。

接下来我们继续,相比大家都想知道汇编语言是怎么转成二进制机器语言。以下是MIPS指令各字段的命名以及含义。分为I型以及R型两类指令格式。

R型:用于寄存器,进行逻辑运算,如加减操作。

op rs rt rd shamt funct
6位 5位 5位 5位 5位 6位
  •  op:指令的基本操作,通常称为操作码(opcode)。
  • rs:第一个源操作数寄存器。
  • rt:第二个源操数寄存器。
  • rd:用于存放操作结果的目的寄存器。
  • shamt:位移量。
  • funct:功能码(function code)。

I型:用于立即数,即立即数与数据传输指令,如sw,lw等操作。

op rs rt constant and adress
6位 5位 5位 16位

 下面列出MPIS常用指令的值给到大家看下:

 指令

格式

op

rs

rt

rd

shumt

hinct

address

add

R

0

reg

reg

reg

0

32

n. a.

Iw (load word)

I

35

reg

n. a

n. a n. a n. a address

在上表中,“reg”代表寄存器的标号(从0 ~31), “address”表示16位地址, “na.” (not applicable)表示这个字段在该指令格式中不出现。注意,add指令在硬件是根据hmct字段的值来决定所进行的操作:add (32)或substract (34)

因此针对上面转换,可以得到:

    汇编语言                                             

 add: 

  add  $a2,$a0,$a1  //c=a+b                    
  add  $v0,$a2,$zero              
  jr      $ra        
}

op

rs

rt

rd

address/shumt

hinct

0

4

5

6

0

32

6

0

2 0 32
0 31 0 0 0 8

转换为二进制:

op

rs

rt

rd

address/shumt

hinct

000000

00100

00101

00110

00000

100000 

000000 

00110

00000

00010 00000 100000
000000 11111 00000 00000 00000 001000

到这里,相必大家都有点感觉了,实际一个程序的指令是涉及很多指令计算的。远远超过以上三条,因此大家需要去强化学习,加深对计算机的理解。 

参考文献:

[1]计算机组成与设计:硬件/软件接口(原书第5版).北京:机械工业出版社,2015.

发布了3 篇原创文章 · 获赞 0 · 访问量 69

猜你喜欢

转载自blog.csdn.net/taipoucha5799/article/details/104956366
今日推荐