Assembly 使用EXT和扩展数字。还有ASR和LSL的工作原理(68000汇编语言)
我正在学习汇编语言(用于68000微处理器),遇到了以下问题: 编写一个68000汇编语言程序,执行5*X +6*Y+[Y/8]->[D1.L],其中x是存储在 D0和Y是存储在D1的上16位的16位有符号数字。忽略其余的 是的 这就是解决方案:Assembly 使用EXT和扩展数字。还有ASR和LSL的工作原理(68000汇编语言),assembly,68000,Assembly,68000,我正在学习汇编语言(用于68000微处理器),遇到了以下问题: 编写一个68000汇编语言程序,执行5*X +6*Y+[Y/8]->[D1.L],其中x是存储在 D0和Y是存储在D1的上16位的16位有符号数字。忽略其余的 是的 这就是解决方案: ANDI.W #$OOFF,DO ;CONVERT X TO UNSIGNED 16-BIT MULU.W #5,DO ;COMPUTE UNSIGNED 5*X IN D0.L
ANDI.W #$OOFF,DO ;CONVERT X TO UNSIGNED 16-BIT
MULU.W #5,DO ;COMPUTE UNSIGNED 5*X IN D0.L
SWAP.W D1 ;MOVE Y TO LOW 16 BITS IN D1
M0VE.W D1 ,D2 ;SAVE Y TO LOW 16 BITS OF D2
MULS.W #6,D1 ;COMPUTE SIGNED 6*Y IN D1.L
ADD.L DO,D1 ;ADD 5*X WITH 6*Y
EXT.L D2 ;SIGN EXTEND Y TO 32 BITS
ASR.L #3,D2 ;PERFORM Y/8;DISCARD REMAINDER
ADD.L D2,Dl ;PERFORM 5*X+6*Y +Y/8
FINISH JMP FINISH
然而,我不明白第一行。我想我们必须把它转换成16位,因为Y是一个16位的有符号数,但我不知道在这种情况下,ANDI
指令是如何工作的
此外,在示例中,他们使用ASR.L#3,D2
将D2除以8;所以如果我使用ASR.L#2,D2,那么我将D2除以4?或者它是如何工作的
如果我使用LSL.L#3,D2,那么我将D2乘以8
最后,为什么他们要把Y扩展到32位
谢谢你的帮助 我不知道有68000个asm,但我想ANDI将是立即的,所以
result_16b=0x00FF&X_8b代码>这将确保结果的上8位为零,下8位包含X值
向左/向右移动实际上是乘以/除以2的幂
考虑二进制8b中的值10
:
0000 1010
(8+2=10)
0001 0100
左移1档=16+4=20(10*2)
0000 0101
10在向右移动1个位置=4+1=5(10/2)
0000 0010
10向右移动2个位置=2(10/4截断)
因此,在某些CPU上执行X*5可能比使用MUL
更快:
将放入D1
16b无符号数,从D0中的8b无符号扩展而来。作为练习,我将让您自己计算这一点。:)
因此,不要盲目地学习“如何做那件事”,而要始终检查您是否完全了解操作及其目的。这将使您能够更快地构建自己的解决方案。毕竟,事实上,使用CPU可以进行的基本操作很少
一般来说,所有CPU都有(并非所有CPU都有,但从基本CPU开始,就有足够的CPU来模拟其余CPU):
- 位操作:旋转、移位和或、异或(EOR)、非和复制(移动/加载/存储变体)(x86测试)
- 很少有算术部件像:NEG、ADD、SUB、MUL、DIV、INC、DEC(还有一些比较)
- 跳转/呼叫/返回和其他流量控制操作
- 堆栈实用程序函数:push/pop/。。。(可通过移动/添加/订阅模拟)
- 其他一切通常要么是CPU/平台的专用控制,要么是基础的专用/复杂变体,或者是更高的数学函数,如sin/cos/
因此,如果您学习了前三组,并习惯于在位级别上思考它们,那么在短时间内学习了“不同”汇编程序的语法之后,您可以在任何其他CPU上取得相当大的进步。这些是相当普遍的。这在用高级语言编程时也有帮助,因此更好地了解什么是CPU的廉价本机操作,什么是更复杂的计算,这样您就可以选择更简单的问题解决方案。我不知道68000 asm,但我想ANDI将立即使用,所以result_16b=0x00FF&X_8b代码>这将确保结果的上8位为零,下8位包含X值
向左/向右移动实际上是乘以/除以2的幂
考虑二进制8b中的值10
:
0000 1010
(8+2=10)
0001 0100
左移1档=16+4=20(10*2)
0000 0101
10在向右移动1个位置=4+1=5(10/2)
0000 0010
10向右移动2个位置=2(10/4截断)
因此,在某些CPU上执行X*5可能比使用MUL
更快:
将放入D1
16b无符号数,从D0中的8b无符号扩展而来。作为练习,我将让您自己计算这一点。:)
因此,不要盲目地学习“如何做那件事”,而要始终检查您是否完全了解操作及其目的。这将使您能够更快地构建自己的解决方案。毕竟,事实上,使用CPU可以进行的基本操作很少
一般来说,所有CPU都有(并非所有CPU都有,但从基本CPU开始,就有足够的CPU来模拟其余CPU):
- 位操作:旋转、移位和或、异或(EOR)、非和复制(移动/加载/存储变体)(x86测试)
- 很少有算术部件像:NEG、ADD、SUB、MUL、DIV、INC、DEC(还有一些比较)
- 跳转/呼叫/返回和其他流量控制操作
- 堆栈实用程序函数:push/pop/。。。(可通过移动/添加/订阅模拟)
- 其他一切通常要么是CPU/平台的专用控制,要么是基础的专用/复杂变体,或者是更高的数学函数,如sin/cos/
因此,如果您学习了前三组,并习惯于在位级别上思考它们,那么在短时间内学习了“不同”汇编程序的语法之后,您可以在任何其他CPU上取得相当大的进步。这些是相当普遍的。这也有助于用高级语言编程,因此更好地了解什么是廉价的CPU本机操作,什么是更复杂的计算,这样您就可以选择更简单的问题解决方案。原始帖子中的答案效率非常低。应尽可能避免MULU和DIV指令,因为它们分别需要大约70/140个周期,而“正常”指令时间在4到12个周期之间
首先,您可以更改方程式,以便在编码时更好地工作
5 * X + 6 * Y = (X + Y) * 4 + X + 2 * Y
= (X + Y) << 2 + X + Y + Y
回答您的问题:
EXT执行有符号扩展,因为值的顶部位本质上是一个指示符,指示它是正的还是负的。清除一个
EOR.W D1,D1
MOVE.B D0,D1
5 * X + 6 * Y = (X + Y) * 4 + X + 2 * Y
= (X + Y) << 2 + X + Y + Y
ORG $1000
; Compute 5*X + 6*Y + [Y/8] -> [D1.L],
; X = D0.B (unsigned). Y = top 16 bits D1 (signed)
START
MOVEQ #0,D2 ; MOVEQ faster than CLR
MOVE.B D0,D2 ; D2 now 32 bit X
SWAP D1 ; move Y to bottom 16 bits
EXT.L D1 ; extend to long word.
MOVE.L D1,D3 ;
ADD.L D2,D3 ; add X
LSL.L #2,D3 ; multiply by 4 = 4(X+Y)
ADD.L D2,D3 ; add another X
ADD.L D1,D3
ADD.L D1,D3 ; add another 2 Y
ASR.L #3,D1 ; Y/8
ADD.L D3,D1 ; add (5X+6Y)
FINISH
END START