Easy68k,实现这个 while 循环
Easy68k, Implementing this while loop
int X = 0;
int Y = 1;
while(X <= 10 ){
if(X%2 == 0)
Y = Y * X;
else
Y++;
X++;
}
cout << "Y is: " << Y;
这是我的 Easy68k 代码。
ORG 00
START: ; first instruction of program
MOVE.W #0,D1 ;PUT 0 IN D1 (X)
MOVE.W #1,D2 ;PUT 1 IN D2 (Y)
LOOP CLR.W D3 ;Find the remainder
MOVE.W D1,D3
DIVU #2,D3
SWAP D3
CMP #0,D3 ;Compare remainder with 0
BEQ EQUAL ;If equal, then go to equal
ADD.W #1,D2 ;Y++
ADD.W #1,D1 ;X++
CMP #11,D1 ;Compare D1 with 11
BEQ DONE ;If D1 equals 11, break loop.
BRA LOOP
EQUAL MULU.W D1,D2 ;Multiply D1 and D2 and store it in D2
ADD.W #1,D1 ;X++
CMP #11,D1 ;Compare D1 with 11
BEQ DONE ;If D1 equals 11, break loop.
BRA LOOP
DONE LEA MESSAGE,A1
MOVE.W #14,D0
TRAP #15
MOVE.W D2,D1
MOVE.W #3,D0
TRAP #15
SIMHALT ; halt simulator
MESSAGE DC.W 'Y is: ',0
END START ; last line of source
我不太确定我的代码有什么不正确的地方,但我感觉这是循环部分开头的问题。我已经按照代码进行操作,但我仍然无法弄清楚哪里出了问题。当我 运行 它时,它输出
Y 是:10。
D1 和 D2 也都是 A 或 10。感谢任何帮助。
进行除法和交换后,结果和除法的余数仍然在 d3
中。这意味着它永远不会为零并且比较总是错误的。您需要使用 and
将上部归零或使用仅使用下部的 form.of cmp
。
请注意:当您计算 2 的幂的余数时,您也可以跳过除法并直接使用 and
值减一。在这种情况下,除以二的余数与 and
相同,值为 1.
与使用 divu
相比,使用更高效、更快速的机制来执行与 x%2 相同的操作只是检查位 0 的状态。这也会产生更少的代码。这显然只适用于 2 的 mod,任何其他值都需要另一种方法(甚至可能是可怕的鸿沟 :))
更改现有代码以供阅读(为简洁起见进行了删减):
LOOP CLR.W D3 ;Find the remainder
MOVE.W D1,D3
btst #0,d3 ; Test bit 0
BEQ EQUAL ;If equal, then go to equal
...
执行速度会明显加快(在真实硬件上)。您可能不会注意到 :)
这是有效的,因为 mod 2 本质上告诉您数字是偶数还是奇数,只需查看位 0 是否已设置即可非常便宜地完成此操作
HTH
在 'what is incorrect' 上回答:
LOOP CLR.W D3 ;Find the remainder
MOVE.W D1,D3
DIVU #2,D3
68000 上的 divu.w
和 divs.w
命令从第二个参数中获取完整的 32 位字,并将其除以第一个参数中指定的 16 位字。
您的代码不会在除法之前清除 d3
的高 16 位。
所以变化很明显:
LOOP CLR.L D3 ;Find the remainder
;all the same from here on
int X = 0;
int Y = 1;
while(X <= 10 ){
if(X%2 == 0)
Y = Y * X;
else
Y++;
X++;
}
cout << "Y is: " << Y;
这是我的 Easy68k 代码。
ORG 00
START: ; first instruction of program
MOVE.W #0,D1 ;PUT 0 IN D1 (X)
MOVE.W #1,D2 ;PUT 1 IN D2 (Y)
LOOP CLR.W D3 ;Find the remainder
MOVE.W D1,D3
DIVU #2,D3
SWAP D3
CMP #0,D3 ;Compare remainder with 0
BEQ EQUAL ;If equal, then go to equal
ADD.W #1,D2 ;Y++
ADD.W #1,D1 ;X++
CMP #11,D1 ;Compare D1 with 11
BEQ DONE ;If D1 equals 11, break loop.
BRA LOOP
EQUAL MULU.W D1,D2 ;Multiply D1 and D2 and store it in D2
ADD.W #1,D1 ;X++
CMP #11,D1 ;Compare D1 with 11
BEQ DONE ;If D1 equals 11, break loop.
BRA LOOP
DONE LEA MESSAGE,A1
MOVE.W #14,D0
TRAP #15
MOVE.W D2,D1
MOVE.W #3,D0
TRAP #15
SIMHALT ; halt simulator
MESSAGE DC.W 'Y is: ',0
END START ; last line of source
我不太确定我的代码有什么不正确的地方,但我感觉这是循环部分开头的问题。我已经按照代码进行操作,但我仍然无法弄清楚哪里出了问题。当我 运行 它时,它输出 Y 是:10。 D1 和 D2 也都是 A 或 10。感谢任何帮助。
进行除法和交换后,结果和除法的余数仍然在 d3
中。这意味着它永远不会为零并且比较总是错误的。您需要使用 and
将上部归零或使用仅使用下部的 form.of cmp
。
请注意:当您计算 2 的幂的余数时,您也可以跳过除法并直接使用 and
值减一。在这种情况下,除以二的余数与 and
相同,值为 1.
与使用 divu
相比,使用更高效、更快速的机制来执行与 x%2 相同的操作只是检查位 0 的状态。这也会产生更少的代码。这显然只适用于 2 的 mod,任何其他值都需要另一种方法(甚至可能是可怕的鸿沟 :))
更改现有代码以供阅读(为简洁起见进行了删减):
LOOP CLR.W D3 ;Find the remainder
MOVE.W D1,D3
btst #0,d3 ; Test bit 0
BEQ EQUAL ;If equal, then go to equal
...
执行速度会明显加快(在真实硬件上)。您可能不会注意到 :)
这是有效的,因为 mod 2 本质上告诉您数字是偶数还是奇数,只需查看位 0 是否已设置即可非常便宜地完成此操作
HTH
在 'what is incorrect' 上回答:
LOOP CLR.W D3 ;Find the remainder
MOVE.W D1,D3
DIVU #2,D3
68000 上的 divu.w
和 divs.w
命令从第二个参数中获取完整的 32 位字,并将其除以第一个参数中指定的 16 位字。
您的代码不会在除法之前清除 d3
的高 16 位。
所以变化很明显:
LOOP CLR.L D3 ;Find the remainder
;all the same from here on