有人可以向我解释以下内容吗?
以下是最小长度ARM指令序列,它将R1乘以常量0x0110 003F而不使用乘法指令
ADD r2, r1, r1, LSL #4 //r2 = 0x11 * r1
RSB r3, r1, r1, LSL #6 //r3 = 0x3F * r1
ADD r3, r3, r2, LSL #20 //r3 = 0x0110 003F * r1
Run Code Online (Sandbox Code Playgroud)
我不确定为什么0x11和0X3F以前习惯0x0110 003F
任何熟悉ARM体系结构或hex的人都能为我解释一下这个程序吗?为什么使用RSB?
数学与ARM无关......
ADD r2,r1,r1, LSL #4 r2 = r1 + (r1 << 4);
RSB r3,r1,r1, LSL #6 r3 = (r1 << 6) - r1;
ADD r3,r3,r2, LSL #20 r3 = r3 + (r2 << 20);
Run Code Online (Sandbox Code Playgroud)
还记得小学的倍增吗?
123
x 12
=====
246
+123
=====
1476
Run Code Online (Sandbox Code Playgroud)
现在关于二进制乘法的一个非常酷的事情是你要么将数字乘以1或0(每个幂2).在one列上方的十进制数学中,base(10)到power 0,其中有一个2.在二进制(基数2)中,我们不会有这种情况.对于数十列(基数到幂1),就像我们将在二进制中看到的那样,取最顶部的数字并将其乘以基数到幂1(向左移一个位置)并将其加到/累加到结果中.
所以,如果我想,在基数2(二进制)中将某些东西乘以0b1011,我将位3,1和0设置为,
result = (x<<3) + (x<<1) + (x<<0);
Run Code Online (Sandbox Code Playgroud)
要乘以0x0110003F,我们可以为8位中的每一位做一个加法
result = (r1<<24)+(r1<<20)+(r1<<5)...
Run Code Online (Sandbox Code Playgroud)
但我们可以使用更基本的数学.
rx * 0x3F
0x3F = 0x40 -1
rx * 0x3F = rx * (0x40 - 1)
distribute
rx * 0x3F = (rx * 0x40) - (rx * 1)
rx * 0x3F = (rx * 0x40) - rx
we know from the comments above that
rx * 0x40 = rx << 6
rx * 0x3F = (rx << 6) - rx
Run Code Online (Sandbox Code Playgroud)
现在
ADD r2,r1,r1,lsl 4 r2 = r1 + (r1 << 4)
r2 = r1 + (r1 << 4)
r2 = r1 + (r1 * 0x10)
r2 = (r1 * 1) + (r1 * 0x10)
r2 = r1 * (1 + 0x10)
r2 = r1 * 0x11
Run Code Online (Sandbox Code Playgroud)
所以
r3 = r1 * 0x3F
r2 = r1 * 0x11
Run Code Online (Sandbox Code Playgroud)
最后一步是
result = r3 + (r2<<20)
result = (r1 * 0x3F) + ((r1*0x11)<<20)
result = (r1 * 0x3F) + ((r1*0x11)*0x100000)
result = (r1 * 0x3F) + (r1*0x1100000)
result = r1 * (0x3f + 0x1100000)
result = r1 * 0x110003F
Run Code Online (Sandbox Code Playgroud)
使用反向减法的原因是因为执行
r3 = (r1 << 6) - r1
Run Code Online (Sandbox Code Playgroud)
使用ARM指令可以通过以下几种方式完成:
mov r3,r1,lsl 6 r3 = (r1 << 6)
sub r3,r3,r1 r3 = r3 - r1
Run Code Online (Sandbox Code Playgroud)
要么
rsb r3,r1,r1,lsl 6 r3 = (r1 << 6) - r1
Run Code Online (Sandbox Code Playgroud)
rsb只表示反向减法,正常减法
sub ra,rb,rc means ra = rb - rc
Run Code Online (Sandbox Code Playgroud)
反向减法意味着反转操作数的顺序
rsb ra,rb,rc means ra = rc - rb
Run Code Online (Sandbox Code Playgroud)
要像这样对三种寄存器格式进行手臂操作数的移位,它必须是最后一个操作数,所以如果你想减去左减操作数,那么使用rsb.
sub ra,rb,rc,lsl x means ra = rb - (rc << x)
rsb ra,rb,rc,lsl x means ra = (rc << x) - rb
Run Code Online (Sandbox Code Playgroud)
我们希望rsb表单保存指令.
| 归档时间: |
|
| 查看次数: |
4716 次 |
| 最近记录: |