2011-10-18 14:53 11人阅读 收藏 举报 简单介绍
RISC CPU是众多CPU中的一种. RISC号称的是精简指令集的CPU. 也就是说, 它的指令系统一般都十分简洁.本文将要介绍的是RISC CPU中目前十分普遍的ARM CPU.
目前很多的RISC CPU均是使用的32BIT长度的指令. 也就是每个指令长度为32BIT. (也有很多RISC CPU提供16BIT长度的指令系统,用于缩短代码长度)
所有的代码均长度为32BIT意味着CPU DESIGNER可以比较省力地涉及CPU. 而CPU DECODE代码的速度也可以相对快很多.
2. 问题所在和解决
我们可以看到INTEL系列的CPU指令长度是不固定的. 从1BYTE~15BYTE.均是允许范围之内的. 这样的话, 我们就可以看到一条JMP XXXXXXXX的指令会被编译成5个字节长度. 一条指令便解决了一条附带有32BIT操作数的操作. 但是RISC无法这样处理. 在ARM的CPU中, 所有指令均是32BIT. 这样,32BIT的操作数就无法直接处理了. 我们举例说明.
在INTEL 386以上的CPU上, 我们可以直接加载1个32BIT VALUE到EAX.
MOV EAX,12345678H
在对应的ARM CPU上,编译器提供的是对等的操作
也是MOV指令
MOV R0,=0x12345678
但是我们可以发现, 这样的指令是无法通过编译的. 因为MOV指令只能有8BIT的操作数!!! 太离谱了. 那我们如何处理呢?
OK. 现在是编译器帮忙的时候了.
我们提供给编译器一条指令
LDR R0,=0X12345678
编译器就必须识别=0X12345678是否可以被精简到8BIT. 显然不行! 编译器接下来的方案就是要把32BIT的常量, 放置到内存的某个地址, 让寻址指令来处理.
现在编译器将尝试将0X12345678放置到CODE SECTOIN的尾部. 然后通过一条
LDR R0,(某地址)的指令来解决. 这就是一般的解决之道.
呵呵, 但是我们必须再度想一下,LDR指令能寻址多远呢? LDR指令最多处理4K的偏移!!! 也是因为CPU指令集的问题. 我们的CODE SECTION如果很大, 导致0X12345678放置的地方超过了LDR指令寻址能力, 将再度出现错误! OK, 了解了这点, 我们就应该能够预防这里问题的出现. 我们需要的是让编译器尽可能近地处理这个常量. 查看一下编译器手册, 请使用LTORG巴. LTORG将立刻在当前计数器上放置所有的那些已经出现,并且需要解决的常量. 这样,我们在那些FUNC的尾部加上LTORG指令, 就可以处理调那些加载常量导致的麻烦.
例:
STMFD SP!,{r0-rx};PUSH STACK
...FUNC BODY...
LDMFD SP!,{r0-rx};POP STACK
MOV PC,LR ;RETURN
LTORG ;RESOLVE LITERAL POOL