关于arm逻辑移位指令,高人指点
左移n位实现乘以2^n,这个是二进制整数的性质。
用左移实现乘法比较快。左移需要1周期,MUL至多需要5周期。在长度不会超过寄存器字长的情况下,推荐用移位实现乘、除法。
你给的程序大意是:
在0x4003001处有个整数,它是从0开始索引的编号。 由于一个指令4个字节,所以乘4找到对应程序的入口。
当执行到LDR PC那句时,PC=LDR所在位置+8(稍后解释),也就是两条指令之后,跳过了NOP,所以我们将这个位置加上刚才的偏移,就得到FUN_TAB各行的地址,解引用之,得到真正的服务程序的地址(比如FUN_SUB0),赋给PC,实现了查表跳转。
我来解释索引从0开始,以及为什么PC...全部
左移n位实现乘以2^n,这个是二进制整数的性质。
用左移实现乘法比较快。左移需要1周期,MUL至多需要5周期。在长度不会超过寄存器字长的情况下,推荐用移位实现乘、除法。
你给的程序大意是:
在0x4003001处有个整数,它是从0开始索引的编号。
由于一个指令4个字节,所以乘4找到对应程序的入口。
当执行到LDR PC那句时,PC=LDR所在位置+8(稍后解释),也就是两条指令之后,跳过了NOP,所以我们将这个位置加上刚才的偏移,就得到FUN_TAB各行的地址,解引用之,得到真正的服务程序的地址(比如FUN_SUB0),赋给PC,实现了查表跳转。
我来解释索引从0开始,以及为什么PC会超前2条指令的原因:ARM 7是三级流水线结构(ARM9是5条,但是前3条作用相同),分别是预读、译码、执行,所以当你看到LDR那句的时候,还没有读取它,当它真正执行的时候,已经三条指令过去了,所以执行的时候会超前2条(本条不算)。
其实你的程序还有优化的余地。比如使用更加实用、安全、快捷的:
ADDLO PC,PC,R2,LSL #2
当然,整个程序就不是你这个写法了。
。收起