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的地址空间。(每个程序运行的时候都有一个运行地址,称之为整个程序的基址)

  • 相关阅读:
    SQL Server事务执行一半出错是否自动回滚整个事务 【转】
    html5 canvas做的俄罗斯方块
    laravel-admin 模型创建、数据迁移、以及关联模型控制器
    laravel-admin 安装
    Composer 安装时要求输入授权用户名密码?
    查找mysql中未提交的事务
    SSH 登录时出现如下错误:No supported key exchange algorithms
    MySQL运行一段时间后自动停止问题的排查
    浅谈PHP中的数组和JS中的数组
    MySQL中使用group_concat()函数数据被截取(有默认长度限制),谨慎!
  • 原文地址:https://www.cnblogs.com/autum/p/ARM.html
Copyright © 2011-2022 走看看