龙空技术网

C-Code:一种中间语言和它对应的虚拟机

余生做酒长醉不忧 329

前言:

如今你们对“c语言r0”都比较关心,小伙伴们都需要剖析一些“c语言r0”的相关资讯。那么小编也在网络上搜集了一些有关“c语言r0””的相关内容,希望同学们能喜欢,你们快快来学习一下吧!

中间语言的语法格式多种多样,最主要的就是要兼容运行她的虚拟机,我们的编译器将构建一种编程语言,称之为C-code,这种中间语言,其语义尽可能贴近c语言,从本节开始我们详细讨论中间语言c-code,以及运行她的虚拟机。

基础数据类型:我们将设计虚拟机,使得它能对四种类型的数据信息存储和运算,8-bit-byte,16-bit word 32-bit long word,以及指针,指针本质上是32位的long word,这四种类型的关键字:byte、word、lword、ptr。

如果要定义对应的类型数组,我们可以使用array关键字。如果要定义不同数据类型组成的结构体,我们可以使用关键字record。

虚拟机的组成:寄存器,堆栈和内存。

我们要设计的虚拟机,有16个寄存器,分别命名r0、r1、r3....rF,每个寄存器都是32位,代码指令可以像读取普通数据类型一样对任意一个寄存器进行读写,由于寄存器是32位的,那么指令也可以把寄存器的8位,16位做为一个整体进行读取。

h3 h2 h1 h0

r0

r1

rF

我们可以通过下面方式来对寄存器进行读取:

r1.pp:把r1寄存器当做指针使用

r1.l : 把r1作为32位数据使用

r1.w.high(h3,h2)

r1.w.low(h1,h0) : 把r1当做两个16位数据使用

r1.b.b3(h3)

r1.b.b2(h2)

r1.b.b1(h1)

r1.b.b0(h0) 把r1当做8位数据使用

虚拟机还将设置一个堆栈,这个堆栈将还有1024个元素,每个元素是一个32位的存储单元,同时还要两个栈指针:

堆栈还会附带两个指针分别是SP,FP,熟悉汇编语言的同学应该知道这两个指针的作用。

虚拟机还有一个指针叫IP,用于指向下一个语句,每执行一条语句后,ip的值就会发生变化,例如一条call指令,会将当前ip的值压入堆栈,然后ip将指向call对象所对应的代码地址,ret语句会想存储在堆栈上的地址写入ip寄存器,而goto会直接修改ip的值,使得它对应于跳转的地址。

内存的构造:段

当一个可执行程序加载到虚拟机内存后,它的内存布局如下:

红色部分属于可执行文件,因此他们是可以存放在硬盘上的,当程序加载执行后,会被读入内存,同时,虚拟机会为执行的程序分配堆栈端和堆段,,堆段用于动态分配内存。

Header是可执行文件的头部,用来描述可执行文件各部分的相关信息,以便于系统加载,大家如果熟悉linux开发的话,linux可执行文件elf都含有一个头部,我们这个头部与elf的头部类似。

可执行文件被加载到内存后,形成上面的内存结构,我们叫做可执行映像,executable image,可执行文件的代码段和数据段会直接拷贝进内存,数据段包含的是初始化了的数据,这种数据包含两部分,一部分是富余了初值的变量,一部分是常量数据,有时候常量数据会直接放在代码段,从而能够增加程序的运行速度,售后一段时间我们会推出一门课构建操作系统,可以看到我是如何将常量放到代码段的。

当数据段和代码段被加载入内存后,操作系统或许会直接将控制权交给程序,要不就会构建一些专用数据,例如bss段,bss段用来存放未初始化的全局变量,操作系统会构建bss段,并将所以未初始化的变量赋初值0.操作系统还会初始化堆栈寄存器sp,使它指向堆栈段的某个地方,堆栈将用于程序在运行时存储局部变量,进行函数调用时的参数传递等等。在多数情况下堆栈的扩展是由上到下,所以堆栈指针一般设置为指向堆栈段的顶端。堆(heap)是用来分配动态内存,例如C语言的malloc, free 等内存的分配和释放都作用在堆上。C++的new也是在堆上为对象分配一块内存,然后对分配的内存运行初始化构造函数来初始化内存数据。

标签: #c语言r0