S = (0x01 << 26) if offset < 0 else 0

则J1,J2的可以按如下计算

J1, J2 = (1 if I1 else 0, 1 if I2 else 0) if S else (0 if I1 else 1, 0 if I2 else 1)
J2 <<= 11
J1 <<= 13

1. 算法1

    def signExtend(address, entry):
        offset = entry - address - 4
        imm32 = offset & 0x7fffffff
        # contains the sign bit
        S = (0x01 << 26) if offset < 0 else 0
        imm11 = (imm32 & 0x00000FFE) >> 1  # [11: 1]
        imm10 = (imm32 & 0x003FF000) >> 12 << 16  # [21: 12]
        I2 = imm32 & (0x01 << 22)
        I1 = imm32 & (0x01 << 23)
        J1, J2 = (1 if I1 else 0, 1 if I2 else 0) if S else (0 if I1 else 1, 0 if I2 else 1)
        J2 <<= 11
        J1 <<= 13
        code = 0xF0000000  # [31: 27], BL
        instr = code | S | imm10 | 0x0000C000 | J1 | 0x00001000 | J2 | imm11
        imm32 = ((instr & 0xffff) << 16) | ((instr >> 16) & 0xffff)
        return imm32

2. 算法2

    def signExtend2(address, entry):
        imm32 = (entry - address - 4) // 2
        low = 0xF800 | (imm32 & 0x7FF)
        high = 0xF000 | (0x03 << 9) | ((imm32 >> 11) & 0x1FF)
        return ((low << 16) | high)

3. 算法3

    def signExtend3(address, entry):
        offset = ( entry - address - 4 ) & 0x007fffff
        high = 0xF000 | offset >> 12
        low = 0xF800 | (offset & 0x00000fff) >> 1
        imm32 = (low << 16) | high
        return imm32

测试示例:

    data  = signExtend(0x20001580, 0x20000074)
    data2 = signExtend2(0x20001580, 0x20000074)
    data3 = signExtend3(0x20001580, 0x20000074)
    print('0x{:08X}'.format(data))
    print('0x{:08X}'.format(data2))
    print('0x{:08X}'.format(data3))
0xFD78F7FE
0xFD78F7FE
0xFD78F7FE
# instr = 0xFD78F7FE
# print(bin(instr))
# 11110 1 1111111110 11 1 1 1 10101111000
#       S  imm10       J1  J2   imm11
另外说明一下,对于小系统来说,S, J1, J2,受限于内存,三者在算法1中,都能得到,所以才有2,3的简化算法取值;
在ARM手册中BL指令如下描述(其后跟立即数的描述如下,跟寄存器直接看手册很简单):其中比较难理解的就是J1,J2的获取,在手册中有描述,请看如下所示:I1,I2就是立即数的bit[23:22]两个bit位。# imm32表示立即数I2 = imm32 &amp; (0x01 &lt;&lt; 22) I1 = imm32 &amp; (0x01 &lt;&lt; 2...
注:文章详细请参考http:// bl og.sina.com.cn/s/ bl og_58f750e80100fr3p.html http:// bl og.sina.com.cn/s/ bl og_a4cdf30501018317.html 指令 B与 BL 的区别  B常用于不返回的跳转,比如跳到某个标号处, BL 则用于子程序跳转(要返回,返回地地存于LR) B. (注意B后面的“.”)这个“.”是
文章目录1、为什么要有相对跳转和绝对跳转?2、在程序 只有相对跳转/绝对跳转是否可以?3、B( BL )执行过程分析4、LDR 指令 执行过程分析5、B( BL )和LDR跳转范围是如何规定的? 1、为什么要有相对跳转和绝对跳转? 顺序执行: 指令 一条一条按照顺序往下执行,比如变量的定义和赋值都是按照顺序执行的。 跳转执行:当 指令 执行到当前位置后跳转到其他位置执行。比如,在主函数 调用其他函数就是典型的跳转执行。其 跳转又分为绝对跳转和相对跳转。 绝对跳转:直接跳转到一个固定的,实实在在的地址。 相对跳转:相对于当前pc
即它的地址与代码处于的位置相关,是绝对地址 BL :带链接分支跳转 指令 ,也是位置无关码(相对位置),用于调用函数用的。 B:分支跳转 指令 ,指目标不能太远,一般用于同一个文件下的目标地址跳转。 LDR:通常都是作加载 指令 的,但是它也可以作伪 指令 ,通常有两种不同的表示: 1)...
B 和 BL 指令 都是 相对跳转(短跳转) 指令 ,通过偏移量跳转, 最大跳转距离是 ±32M 使用 mov pc, <>可以实现 对跳转(长跳转)(不会保存当前 PC 值) 关于B 指令 BL 指令 最大跳转距离是 ±32M: ARM 汇编每条 指令 占用 4byte,生成 机器码 B 、 BL 存放在bits[31:24], bits[23:0]是立即数空间,可以表示 2^24个地址。由于每条汇编...
SUB是一个通用的减法 指令 ,在不同的架构和处理器 具体的 指令 格式和 机器码 指令 格式会有所不同。以下是一些常见架构和处理器 SUB 指令 的汇编 指令 格式和 机器码 指令 格式: 1. x86架构 SUB 指令 的汇编 指令 格式为: SUB destination, source 其 destination表示被减数,source表示减数。可以是寄存器、内存地址或立即数。 机器码 指令 格式根据不同的寻址方式而有所不同。 2. ARM 架构 SUB 指令 的汇编 指令 格式为: SUB{S}{cond} Rd, Rn, Operand2 其 S表示是否更新条件标志位,cond表示条件码,Rd表示目的寄存器,Rn表示源寄存器,Operand2可以是寄存器、移位寄存器、立即数或寄存器加移位寄存器。 机器码 指令 格式和条件码有关。 3. MIPS架构 SUB 指令 的汇编 指令 格式为: SUB Rd, Rs, Rt 其 Rd表示目的寄存器,Rs表示被减数寄存器,Rt表示减数寄存器。 机器码 指令 格式根据寄存器编号而有所不同。 需要注意的是,不同的处理器和架构 指令 格式可能会有所不同,以上仅为一些常见处理器和架构 的SUB 指令 格式。