我目前正在尝试了解如何通过在装配中左移来进行倍增,从而解决一些任务。
我被要求重写一些计算,以便不使用mul
或div
。
示例:
mul $2, %eax
我的回答:
sal $1, %eax
据我所知,通过向左移动一次,可以回答这个问题。 但另一个例子说
mul $3, %eax
和
mul $5, %eax
我该如何解决?从我学到的东西就像分裂它然后以某种方式将它们加在一起。
任何?谢谢!
答案 0 :(得分:3)
您需要通过加法和移位操作来分解乘法,例如
x*3 == x*2 + x
然后它变得微不足道
mov %eax, %ebx # tmp = eax
sal $1, %eax # eax <<= 1
add %ebx, %eax # eax += tmp
答案 1 :(得分:2)
通过移位,您只能乘以{除以<asp:Button ID="btnSignup" runat="server"
Style="width: 150px; height: 40px; border-radius: 2px; font-weight: bold; background-color: #499234; margin-left: 70px; margin-top: 10px"
Text="Create New Account"
CausesValidation="true"
ValidationGroup="signupGroup"
PostBackUrl="~/Page2.aspx" <%-- removing this doesn't work either --%>
OnClick="btnSignup_Click" />
的幂。
2
如果要乘以x * (2^n) = x << n
x / (2^n) = x >> n
,而x * y
不是2的幂,则需要将其“分解”为2的幂,乘以每个分量并添加结果。
幸运的是,任何数字都可以表示为两个幂的总和。你猜怎么着?二进制表示正好告诉你如何。例如:
y
二进制表示将是
y = 12 (not a power of two).
现在选择以下位置:y = 1100
(从右侧的2, 3
开始)。这意味着
0
现在,要将y = 2^2 + 2^3.
乘以x
,您只需要:
y
你已经用移位和加法替换了乘法。
(顺便说一句,如果你熟悉二进制文件的长乘法方法,你会在这里认出来......)
答案 2 :(得分:0)
这个问题刚刚被问到并回答了......
从小学我们知道
n * 3 = n * (2 + 1) = n * ((2^1) + (2^0)) = (n*(2^1)) + (n*(2^0))
然后你可以应用转移
(n<<1)+(n<<0)
对于5为0b101或2 ^ 2 + 2 ^ 0相同。
你也可以从gradechool再次长时间乘法,但二进制更简单
nmop
* 0101
=========
nmop
0000
nmop
+0000
=========
(其中n,m,op是单个位)带小数(等级学校)你把数字放在底部并乘以整个顶部,每个10的底部移动一列,同样在二进制文件中,但是只有两个选项,你只有两个选择乘以0或乘以1,所以要么你没有添加内容,要么加上一次乘以正确数量的数字。
无论哪种方式,你得到相同的结果,选择一个操作数,对于每个二进制位是一个,你将另一个操作数移动多个位置,并将其全部添加。
分裂是一个完全不同的野兽,你可以向右移动除以2的幂,但它不会以相同的方式分配n / 5!= n / 4 + n / 1。通过一些技巧让黑客获得高兴的书。还要注意,如果它是2的幂,那么它通常只与无符号数一起使用,带符号的数字经常看到从左边移入的零而不是符号位的重复。在某些体系结构的汇编中,有一个算术右移与逻辑右移,逻辑通常在零中移位,这是高级语言经常使用的移位,算法理想地重复符号位。允许你使用shift right作为两个除数的幂来签名(但不一定是无符号)