ZX81 BASIC中的快速可分性检查

时间:2009-03-15 12:20:00

标签: division z80 zx81

由于许多Project Euler问题要求你进行很多次的可分性检查,我一直试图找出在ZX81 BASIC中执行此任务的最快方法。

到目前为止,我已将(N/D)INT(N/D)进行了比较,以检查N是否可以D分割。 我一直在考虑在Z80 machine code中进行测试,我还没有想出如何在机器代码中使用BASIC中的变量。

如何实现?

5 个答案:

答案 0 :(得分:7)

您可以通过反复减法在机器代码中快速完成此操作。基本上你有一个类似的程序:

set accumulator to N
subtract D
if carry flag is set then it is not divisible
if zero flag is set then it is divisible
otherwise repeat subtraction until one of the above occurs

8位版本将类似于:

DIVISIBLE_TEST:
LD B,10
LD A,100

DIVISIBLE_TEST_LOOP:
SUB B
JR C, $END_DIVISIBLE_TEST
JR Z, $END_DIVISIBLE_TEST
JR $DIVISIBLE_TEST_LOOP

END_DIVISIBLE_TEST:
LD B,A
LD C,0
RET

现在,您可以使用USR从基本呼叫。 USR返回的是BC寄存器对中的任何内容,因此您可能希望执行以下操作:

REM poke the memory addresses with the operands to load the registers
POKE X+1, D
POKE X+3, N
LET r = USR X
IF r = 0 THEN GOTO isdivisible
IF r <> 0 THEN GOTO isnotdivisible

This is an introduction I wrote to Z80 which should help you figure this out.如果您不熟悉它们,这将解释标志。 虽然它是Spectrum而不是ZX81,但是有更多链接可以从主站点获得良好的Z80内容。

16位版本将非常相似,但使用寄存器对操作。如果你需要超过16位,它会更复杂。

如何加载它取决于您 - 但传统方法是使用DATA语句和POKE。您可能更愿意让汇编程序为您找出机器代码!

答案 1 :(得分:4)

您现有的解决方案可能已经足够好了。如果你发现它是分析的瓶颈,只能用更快的东西替换它。

(当然,直言不讳地说。)

无论如何,在ZX81上你可以切换到快速模式。

答案 2 :(得分:2)

不知道ZX81中是否有RANDOMIZE USR,但我认为它可用于调用程序集中的例程。要传递参数,您可能需要在执行RANDOMIZE USR之前使用POKE设置一些固定的内存位置。

我记得在ROM中找到一个例程列表来支持ZX Basic。我确信有一些可以执行浮动操作。

浮点的替代方法是使用定点数学。在没有数学协处理器的情况下,它会快得多。

您还可以在Sinclair用户问题中找到更多信息。他们在ZX Spectrum中发表了一些与编程有关的文章

答案 3 :(得分:0)

首先应将值放在某些预先知道的内存位置。然后使用Z80汇编程序中的相同位置。两者之间没有参数传递。

这是基于我(仍然)记得的ZX Spectrum 48.祝你好运,但你可能会考虑升级你的hw。 ; /

答案 4 :(得分:0)

Z80机器码的问题在于它没有浮点运算(并且没有整数除法或乘法)。在Z80汇编程序中实现自己的FP库并非易事。当然,你可以使用内置的BASIC例程,但是你也可以坚持使用BASIC。