ARM立即数 在 mov r2,#0xffb 这句中,不是MOV的用法出错,而是立即数用法出错。 立即数的用法定义在Arm Architechture Reference Manual(简称ARMARM)的A5-4页开始 很重要的一段: An immdediate operand value is formed by rotating an 8-bit constant (in a 32-bit word) by an even number of bits (0,2,4,8,26,28,30). Therefore, each instruction contains an 8-bit constant and a 4-bit rotate to be applied to that constant. Some valid constants are: 0xFF, 0x104, 0xFF0, 0xFF00, 0xFF000, 0xFF000000, 0xF000000F Some invalid constants are: 0x101, 0x102, 0xFF1, 0xFF04, 0xFF003, 0xFFFFFFFF, 0xF000001F 而在下面的A5-6页中提到
Specifies the immediate constant wanted. It is encoded in the instruction as an 8-bit immediate (immed_8) and a 4-bit immediate (rotate_imm), so that
is equal to the result of rotating immed_8 right by (2*rotate_imm) bits. shifter_operand = immed_8 Rotate_Right (rotate_imm * 2) 以及 Some values of
have more than one possible encoding. When more than one encoding is available, an assembler needs to choose the correct one to use. For more precise control of the encoding, the instruction fields can be specified directly by using the syntax: #
,
所以,综上所述,首先解释清楚了 mov r2,#0xFF,28 一句。28并不是第三个操作数,而是和0xFF并在一起作为立即数使用,将0xFF循环右移28位。而这里必须强调右移XX位必须是个偶数,因为它将等于rotate_imm*2,那么在该指令的机器码中rotate_imm = 14, 也就是在32-BIT的机器码中第11到第8 bit = 1110B 然后再来看 mov r2,#0xFFB 的出错情况 0xFFB = 111111111011B,很显然按照 shifter_operand = immed_8 Rotate_Right (rotate_imm * 2) 的公式, shifter_operand = 0xFFB时无法得到有效的 immed_8 和 rotate_imm, 所以编译出现错误 error A0092: no immediate rotate operand can be created: 4091 也可以理解了,它应该是说无法生成rotate_imm,实际上immed_8也是无法生成的。 关于立即数如何分解成immed_8和rotate_imm,可以参考上面给出的valid constants和invalid constants,简而言之,如果该立即数可以分解成一个8-bit的二进制数循环右移偶数位,那么这个立即数是有效的,反之无效。 在上面的例子中,想要得到 r2 = 0xFFB 那么在汇编里就必须走两步了,一步是无论如何无法到达的。 附上《ARM体系结构与编程》2.2.1数据处理指令的操作数的寻址方式中关于立即数方式的介绍。 每个立即数由一个8位的常数循环右移偶数位得到。其中循环右移的位数由一个4位二进制的两倍表示。则有:
=immed_8循环右移(2*rotate_imm)并不是每一个32位得常数都是合法的立即数,只有能通过上面构造方法得到的才是合法的立即数。ARM汇编编译器按照下面的规则来生成立即数的编码。(1)当立即数数值在0和0xFF范围时,令immed_8=
,rotate_imm=0.(2)其他情况,汇编编译器选择使rotate_imm数值最小的编码方式。
ARM立即数
最新推荐文章于 2022-06-20 21:31:55 发布