ARM指令学习笔记
最后一块是C与汇编混合编程。
(1)c中内嵌汇编。曾今看过个故事:一个物理学家写一个模拟天体运行的程序,分别从算法和指令两方面经行优化,用了一个月的时间将一个原本要几年才能出结果的程序缩短到十几分钟。这其中有个很重要的一步,就是将某些重用性很大的高级语言程序块用汇编语言直接书写。大大缩短了程序运行的极限时间。曾今也好奇过,高级语言里面怎么去内嵌汇编?
_asm
{
指令[;指令]
...
[指令]
}
内嵌汇编程序对寄存器、常量、标号等有很多限制,就不多说了。
(2)汇编中内嵌c语言程序
(3)C与汇编互相调用
在学习ARM指令的过程中,遇到过很多问题,第一次碰到往往非常不解,还有些个该注意的地方,当然了,问题和需呀注意的地方远不止这些。这些只是个人觉得一些比较典型的,写在这里与诸位分享:
1.#immed_8r常数表达式时“该常数必须对应8位位图,即常数是由一个8位的常数循环移位偶数位得到的。”
其意思是这样:#immed_8r在芯片处理时表示一个32位数,但是它是由一个8位数(比如:01011010,即0x5A)通过循环移位偶数位得到(10000000000000000000000000010110,就是0x5A通过循环右移2位(偶数位)的到的)。
而10100000000000000000000000010110,就不符合这样的规定,编译时一定出错。因为你可能通过将10110101循环右移位得到它,但是不可能通过循环移位偶数位得到。
10110000000000000000000000010110,也不符合这样的规定,很明显:101101011有9位。
2.什么叫带符号扩展.
当从16位向32位赋值时,若选择无符号扩展,那高位补零。选择有符号扩展,那32中的16位按照16位最高位补齐。
例如1101010110101010------->11111111111111111101010110101010
0101010110101010------->000000000000000101010110101010
关于为什么这样补,可以参照补码定义,这里介绍一种简单的补码计算方法:
N位绝对值为k的数的补码为:2^n-k.比那个取反加一得来得清爽一点。
3.我们说有四种类型的堆栈寻址方式,LDMFA,STMFA,LDMEA,STMEA。
注意F表示full,E表示empty,A表示after,B表示before。
我们假设:在C语言中stack[]为堆栈数组,top为堆的顶指针。为方便理解。我用c语言描述了一下。
堆栈是一种数据结构,按先进后出(FirstInLastOut,FILO)的方式工作,使用一个称作堆栈指针的专用寄存器指示当前的操作位置,堆栈指针总是指向栈顶。
当堆栈指针指向最后压入堆栈的数据时,称为满堆栈(FullStack),而当堆栈指针指向下一个将要放入数据的空位置时,称为空堆栈(EmptyStack)。
同时,根据堆栈的生成方式,又可以分为递增堆栈(AscendingStack)和递减堆栈(DecendingStack),当堆栈由低地址向高地址生成时,称为递增堆栈,当堆栈由高地址向低地址生成时,称为递减堆栈。这样就有四种类型的堆栈工作方式,ARM微处理器支持这四种类型的堆栈工作方式,即:
◎Fulldescending满递减堆栈
堆栈首部是高地址,堆栈向低地址增长。栈指针总是指向堆栈最后一个元素(最后一个元素是最后压入的数据)。
ARM-Thumb过程调用标准和ARM、ThumbC/C++编译器总是使用Fulldescending类型堆栈。
C语言表示:stack[--top]=value
◎Fullascending满递增堆栈
堆栈首部是低地址,堆栈向高地址增长。栈指针总是指向堆栈最后一个元素(最后一个元素是最后压入的数据)。
C语言表示:stack[top--]=value
◎Emptydescending空递减堆栈
堆栈首部是低地址,堆栈向高地址增长。栈指针总是指向下一个将要放入数据的空位置。
C语言表示:stack[++top]=value
◎Emptyascending空递增堆栈
堆栈首部是高地址,堆栈向低地址增长。栈指针总是指向下一个将要放入数据的空位置。
操作堆栈的汇编指令
C语言表示:stack[top++]=value
4.算术位移/逻辑位移/循环位移
算术位移,逻辑位移逻辑右移最高位补0,最低位进入CF,相当于每移一位除以2,一般对于无符号数使用 如:133/8=16余5 MOVAL,10000101B MOVCL,03H SHRAL,CL AL=10H=16 算术右移最高位(即符号位)保持不变,而不是补0最低位进入CF.相当于每移一位除2,一般对于有符号数使用8/8 MOVAL,10000000B MOVCL,03H SARAL,CL AL=0F0H=-16
----------分别对应逻辑左移、逻辑右移、算术右移、循环右移
5.关于ARM的B,BL跳转指令
假设跳转指令处的地址是A,跳转目标处的地址是B.
B,BL指令保存的是偏移地址,这个地址的计算方法是:
1.B-(A+8).A+8是因为ARM的流水线使得指令执行到A处时,PC实际的值是A+8.2.第一步得到的值是4的倍数,因为ARM的指令是4对齐的,即最低两位为00.于是将这个值右移两位.
3.得到最终偏移
执行时:
1.取出偏移
2.左移两位
3.加入PC,这时PC的值刚好为目标处的地址值,即目标地址指令进入取指,流水线前两级被清空
ARM指令学习笔 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)