要有效进行寄存器分配、寄存器绑定等操作,代码生成器就必须依赖于一套完整的寄存器描述信息。当然,其复杂性很大程度上是依赖于目标机系统结构的。通常,代码生成器需要关注的信息包括寄存器的大小、寄存器的名称、寄存器的关系等。下面引入几个有用的数据结构,描述寄存器的相关信息。
【声明9-1】
声明9-1列出的就是可参与分配绑定的寄存器,该列表中未表现的寄存器(如ebp、esp等)是不参与寄存器分配的。值得注意的是,浮点数据寄存器也是不可绑定的。
【声明9-2】
Size2Reg数组用于描述从字节数到寄存器号的映射关系。第0行记录的是1字节的寄存器,第1行记录的是2字节的寄存器,第2行记录的是4字节的寄存器。其中,“1”表示空项。
【声明9-3】(www.daowen.com)
Reg2Size数组用于描述从寄存器到字节数的映射关系。Reg2Size与Size2Reg是互逆的映射,在分配寄存器时,这两个映射关系是非常有用的。
【声明9-4】
RegRela数组用来描述寄存器之间的依赖关系。在介绍i386结构时,笔者曾提到过关于寄存器交织访问的问题。乍一看,这是一个比较奇怪的特性,但在实际应用中却是非常有用的。这里,需要关注的是寄存器之间的依赖关系。例如,eax寄存器值的改变不仅影响eax本身,还会影响ax、ah、al三个寄存器的状态。同样,ax寄存器值的改变也会影响eax、ah、al三个寄存器的状态。那么,这个依赖关系的作用是什么呢?实际上,代码生成器并不关注某一运行时刻的寄存器的实际存储值,当然,这也是不可能实现的。不过,寄存器在某一运行时刻所绑定的具体变量或存储空间却是代码生成器关心的。而RegRela的依赖关系对于寄存器的绑定是有重要意义的,例如,假设eax被绑定到一个4字节变量时,为了保证代码生成的安全,eax、ax、ah、al四个寄存器的原有绑定必须全部解除。不过,值得注意的是,当ah被绑定时,eax、ax、ah三个寄存器是必须解除原有绑定的,但al的原有绑定是不受影响的。其中,“1”表示空项。
实际上,就可变目标的应用而言,更理想的做法是将寄存器的描述信息以外部格式文件形式存储,与指令模板库类似,代码生成器在初始化时将描述信息读入。不过,为了便于处理,本书略去了这部分实现。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。