ARMv7 T3编码下adds指令的i位(左数第10位)判定方法及imm3与imm8的差异咨询
关于ARMv7 T3编码adds指令的i位判定与imm3/imm8差异
作为经常跟ARM指令编码打交道的开发者,我来帮你把这两个点讲得明明白白:
1. 左数第10位的i位如何确定?
首先明确:T3是Thumb-2的32位指令编码,这里的i位核心作用是选择立即数的生成规则,它的取值完全由你要使用的目标立即数决定。
具体规则拆解:
- 当
i=1时:最终的32位立即数是将imm8的值循环右移(2 × imm3)位得到的——这种逻辑和ARM指令集经典立即数编码一致,专门用来生成那些能通过偶数位循环移位得到的常数(比如0x00020000,本质是0x80循环右移14位)。 - 当
i=0时:最终的32位立即数是将imm8的值左移imm3位得到的——适合生成低位带连续0的常数(比如0x20,就是0x1左移5位)。
判定i位的实操步骤:
- 先检查目标立即数能不能用「imm8左移imm3位」的方式生成(也就是数的低imm3位全为0,且高位部分能塞进8位);如果可以,就用
i=0。 - 如果不行,再看能不能用「imm8循环右移偶数位」的方式生成;如果可以,就用
i=1。 - 要是两种方式都能生成同一个数(比如
0x80,既可以是imm8=0x80左移0位,也可以是imm8=0x20循环右移2位),编译器通常会选编码更紧凑的方式,自己写汇编的话选哪种都合规。
2. imm3与imm8之间的差异是什么?
这两个字段是完全不同的角色,核心差异体现在三个维度:
(1)位宽与取值范围
imm8是8位字段,取值范围是0x00到0xFF(0-255),能承载的基础数值范围更大;imm3是3位字段,取值范围是0到7,只能表示很小的整数。
(2)在立即数生成中的作用
imm8是立即数的原始数值载体,是构成最终32位立即数的核心素材;imm3是移位控制参数,功能由i位决定:- 当
i=0时:imm3是左移的位数,比如imm8=0x1、imm3=5,最终立即数是0x1 <<5 = 0x20; - 当
i=1时:imm3是循环右移次数的一半(实际移位量是2×imm3),比如imm8=0x80、imm3=7,移位量是14位,最终立即数是0x80循环右移14位 =0x00020000。
- 当
(3)能配合生成的立即数类型
- 结合
i=0和imm3,imm8能生成「高位有效、低位全0」的整数(比如0x40、0x800等); - 结合
i=1和imm3,imm8能生成那些位分布零散的常数(比如0x00010000、0x00000080等,只要能通过偶数位循环右移得到)。
内容的提问来源于stack exchange,提问作者Mzq




