• 关于ARM处理器中operand2的理解分析


    http://hi.baidu.com/youliyouli655/blog/item/0f5b30a87ae9a1b6cb130c1c.html

    关于ARM处理器中operand2的理解分析

    写在前面:转了几位大哥的文章做了整理。

    ARM处理器的汇编语言中,对指令语法格式中的的常数表达式有这样的规定:该常数必须对应8位位图,即常数是由一个8位的常数循环移位偶数位得到的。

    首先从ARM指令系统的语法格式说起。

    一条ARM指令语法格式分为如下几个部分:

    {}{S} ,{,}

    其中,<>内的项是必须的,{}内的项是可选的,如是指令助记符,是必须的,而{}为指令执行条件,是可选的,如果不写则使用默认条件AL(无条件执行)

    Opcode   指令助记符,如LDRSTR

    Cond       执行条件,如EQNE

           S           是否影响CPSR 寄存器的值,书写时影响CPSR,否则不影响

           Rd          目标寄存器

    Rn          第一个操作数的寄存器

    shifter_operand      第二个操作数

    其指令编码格式如下:

    31-28

    27-25

    24-21

    20  

    19-16

    15-12

    11-0 12位)

    cond

    001

    opcode

    S

    Rn

    Rd

    shifter_operand

    当第2 个操作数的形式为:#immed_8r常数表达式时该常数必须对应8位位图,即常数是由一个8位的常数循环移位偶数位得到的。

    其意思是这样:#immed_8r在芯片处理时表示一个32位数,但是它是由一个8位数(比如:01011010,即0x5A)通过循环移位偶数位得到(1000 0000 0000 0000 0000 0000 0001 0110,就是0x5A通过循环右移2位(偶数位)的到的)。

    1010 0000 0000 0000 0000 0000 0001 0110,就不符合这样的规定,编译时一定出错。因为你可能通过将1011 0101循环右移位得到它,但是不可能通过循环移位偶数位得到。

    1011 0000 0000 0000 0000 0000 0001 0110,也不符合这样的规定,很明显:1 0110 1011 9位。

    为什么要有这样的规定?

    那位大哥的理解是(小呆:这个的确是很有道理):

    要从指令编码格式来解释(这就是我为什么一开始讲的是指令编码格式),仔细看表格中的shifter_operand所占的位数:12位。要用一个12位的编码来表示任意的32位数是绝对不可能的(12位数有2^12种可能,而32位数有2^32种)。

    但是又要用12位的编码来表示32位数,怎么办?

    只有在表示数的数量上做限制。通过编码来实现用12位的编码来表示32位数。

    12位的shifter_operand中:8位存数据,4位存移位的次数。

    8位存数据:解释了该常数必须对应8位位图

    4位存移位的次数:解释了为什么只能移偶数位。4位只有16种可能值,而32位数可以循环移位32次(32种可能),那就只好限制:只能移偶数位(两位两位地移,好像一个16位数在移位,16种移位可能)。这样就解决了能表示的情况是实际情况一半的矛盾。

    所以对#immed_8r常数表达式的限制是解决指令编码的第二个操作数位数不足以表示32位操作数的无奈之举,但在我看来:这个可以说是聪明的做法。因为如果直接用12位数来表示32位操作数,只能表示0 到(2^12-1)。大于(2^12-1)的数就没办法表示了。而且细细想来“8位存数据,4位存移位的次数,应该是最好的组合了(我并未想过所有的组合,只是顺便试了几个)。

    ARM指令第二操作数#immed_8r详解

    大多数ARM通用数据处理指令有一个灵活的第2操作数(flexible second operand),这里这解释一下其中的一种格式,#immed_8r常量的表达式。常量必须对应于8位位图(pattern)。该位图在32位字中,被循环移位偶数位(0,2,4,...28,30)。合法常量0xff,0xff000,0xf000000f。非法常量:0x101,0xff04

    ARM 32位模式下,一条指令长度为32位,在上述数据处理指令中,操作数212位。所以像0x7f02这样的数,要两条指令才能完成。

    MOV     R3, #0x7F00    E3 A0 3C 7F 该指令自己完成0x7f移位

    ORR     R1, R3, #2

    所以直接是找不到0x7f02

    #immed_8r那个看明白了,但是请问图片里的那个8~11位的循环移位数,0000是不移位;0001是移动2位;0010是移动4位;0011是移动6位这样子吗?那么 0x7F007F左移8位指令中变成4 7F请问为什么老大你给出的是C 7F呢?

    这个大哥犯了一个错误,关于循环移位,其实arm中只有循环右移(ROR)。0x7f0x7f00是通过循环右移24次才实现的,这里每次移动2位所以是12次(0xc


    <script>window._bd_share_config={"common":{"bdSnsKey":{},"bdText":"","bdMini":"2","bdMiniList":false,"bdPic":"","bdStyle":"0","bdSize":"16"},"share":{}};with(document)0[(getElementsByTagName('head')[0]||body).appendChild(createElement('script')).src='http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new Date()/36e5)];</script>
    阅读(927) | 评论(0) | 转发(0) |
    给主人留下些什么吧!~~
    评论热议
  • 相关阅读:
    进制
    变量
    cmd命令和快捷键
    面向对象和面向过程
    iterations 快捷键
    SQL语句分类和语法
    MySQL语法规范
    Web-Scale-IT 到底是啥?
    安全的应用程序开发和应用程序安全防御
    如何像后端一样写前端代码?
  • 原文地址:https://www.cnblogs.com/ztguang/p/12648026.html
Copyright © 2020-2023  润新知