zoukankan      html  css  js  c++  java
  • 精解一些ARM指令

    其实ldr指令分两种:

    1)ldr r0,#100   这是ldr指令

    2) ldr r0,=10000  这是ldr伪指令 编译器在编译伪指令的时候会把伪指令编译成多条指令机器码  (伪操作是不会被编译成指令机器码的)

    这源于一个问题:ldr r0,#10000 在编译这条指令的时候,是会出错的,下面解释下为什么?

    在指令编码的时候,32位中有12位是用来表示立即数的,其中高4位表示循环右移的位数,后8位表示右移前的数,

    一个立即数是这样表示的:将低8位补0扩展为32位,然后循环右移X位,(X为高4位表示的无符号整数*2)例如:低12位为0x512,则表示的立即数是0x04800000

    其实这样表示的立即数的范围是-2的31次方到2的31次方-1,只不过只能表示这其中的2的21次方个数字而已。其中10000就不在其中,所以有了上面的错误。

    ARM为什么这么设计呢?按他得说法是:绝大部分数8位就可以表示了,8位不能表示的就是小概率事件。

    然后特殊的事情用特殊的办法解决,先把立即数放到某个内存地址中去,然后从这个内存地址中把立即数取到寄存器中。这就是第二条指令的本意,有点烦,但这是小概率事件。

    第二条指令在编译时替换为:ldr r0,[pc,#-4]   DCD 10000  其中DCD是给10000分配一个字,4个字节的存储空间,放在文字池中,然后通过相对地址去取这个数,相对地址的计算就是编译器的事了。

    关于BL跳转指令只能在正负32MB范围内的解释:

    BL指令在编码的时候,有24位用于表示相对地址的,(BL跳转的范围有限,这也是ldr给pc赋值跳转的区别),其中最高位是符号位,余下23位表示相对地址,BL都是跳转到某个指令的执行处,一个指令都是占4个字节,就是4个地址,属于字对齐,最低2位地址固定为0,所以可以看做是有25位表示相对地址,所以就有了正负32MB的地址空间。(每个程序运行的时候都有一个运行地址,称之为整个程序的基址)

  • 相关阅读:
    对象布局已知时 C++ 对象指针的转换时地址调整
    采用栈数据结构的二叉树非递归遍历
    ZOJ 3481. Expand Tab
    “金山杯2007逆向分析挑战赛”第一阶段第二题
    “金山杯2007逆向分析挑战赛”第一阶段第一题分析
    对《神奇的C语言》文中例子 5 代码的分析讨论
    对"QQGame-大家来找茬"的辅助工具的改进
    memset 的实现分析
    ZOJ 1958. Friends
    HBase中MVCC的实现机制及应用情况
  • 原文地址:https://www.cnblogs.com/autum/p/ARM.html
Copyright © 2011-2022 走看看