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 & (0x01 << 22) I1 = imm32 & (0x01 << 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
指令
格式。