逐步分解:
原来的:
C = A * B
相当于:
C = 0
while A != 0:
dec A
C += B
相当于:
C = 0
while A != 0:
dec A
# Note: Following block of code changes B but sets it back to
# original value when done
Z = 0
while B != 0:
dec B
inc Z
inc C
B = Z
相当于:
C = 0
Z = 0
while A != 0:
dec A
# Note: Following block of code changes B but sets it back to
# original value when done
while B != 0:
dec B
inc Z
inc C
while Z != 0:
dec Z
inc B
现在我们只需要弄清楚如何翻译这个结构:
while LOOP_VAR != 0:
dec LOOP_VAR
... some code here which does not use LOOP_VAR ...
这可以翻译成:
# Next 4 lines do "if LOOP_VAR == 0: goto loop_end"
inc LOOP_VAR
dec LOOP_VAR # To set flags
jnz loop_again
goto loop_end
loop_again:
... some code here which does not use LOOP_VAR ...
dec LOOP_VAR
jnz loop_again
loop_end:
当然,我们需要将无条件的 goto 转换为有条件的 goto。幸运的是,我们有很多已知为零的变量,因此我们可以测试其中一个是否为零:
# Unconditional jump to "loop_end". Note that Q is always zero.
inc Q
dec Q
jnz loop_end
所以,把所有这些放在一起:
# Next 3 lines do "if A != 0: goto outer_loop_again"
inc A
dec A # To set flags
jnz outer_loop_again
# Unconditional jump to "outer_loop_end". Note that Q is always zero.
inc Q
dec Q
jnz outer_loop_end
outer_loop_again:
# Next 3 lines do "if B != 0: goto addition_loop_again"
inc B
dec B # To set flags
jnz addition_loop_again
# Unconditional jump to "addition_loop_end". Note that Q is always zero.
inc Q
dec Q
jnz addition_loop_end
addition_loop_again:
inc Z
inc C
dec B
jnz addition_loop_again
addition_loop_end:
# Next 3 lines do "if Z != 0: goto move_loop_again"
inc Z
dec Z # To set flags
jnz move_loop_again
# Unconditional jump to "move_loop_end". Note that Q is always zero.
inc Q
dec Q
jnz move_loop_end
move_loop_again:
inc B
dec Z
jnz move_loop_again
move_loop_end:
dec A
jnz outer_loop_again
outer_loop_end:
# Finished!
helt
编辑添加:实际上,有一个稍微简单的方法。我们可以在开始时检查 A 或 B 是否为零,这将其简化为:
# Check if A is zero, and halt if so
# (So that multiplying by zero gives zero)
inc A
dec A # To set flags
jnz a_non_zero
helt # Multiplying by zero gives zero
a_non_zero:
# Check if B is zero, and halt if so
# (So that multiplying by zero gives zero)
inc B
dec B # To set flags
jnz b_non_zero
helt # Multiplying by zero gives zero
b_non_zero:
outer_loop_again:
addition_loop_again:
inc Z
inc C
dec B
jnz addition_loop_again
move_loop_again:
inc B
dec Z
jnz move_loop_again
dec A
jnz outer_loop_again
# Finished!
helt