如何仅使用vvm中的某些函数(如INP
、STO
、LDA
、BR
、BRP
、SUB
、ADD
和OUT
)乘以负数?
我的代码可以乘以正数,但如果第二个输入是负数或零,它就不能正常工作:
in
sto 99
in
sto 98
lda 97
add 99
sto 97
lda 98
sub 90
sto 98
lda 98
brz 13
br 04
lda 97
out
hlt
*90
dat 001
字符串
当第二个输入为零或更小时,程序会继续循环,并最终在add 99
处遇到“Data value out of range(1000)”错误,这意味着结果超过了999。
我被卡住了,我不知道如何解决这个问题。我觉得我需要将输入的负输入转换为正输入,然后像这样将它们相乘,但我不知道如何做到这一点,以及它是否能解决问题。
我如何使它对第二个输入的非正值起作用?
1条答案
按热度按时间lh80um4z1#
实际上,当第二个输入为负或零时,代码无法正常工作。
对于零的情况:你的代码只检查第二个输入(用作倒计数)是否在循环的一次迭代后变为零。这个检查最好在循环的开始时进行,所以它也在开始时执行。
对于负值的情况:在这种情况下,您应该“翻转”两个输入的符号,因为
(-a)*(-b) == a*b
。要“翻转”符号,您可以从0减去原始值,因为0-a == -a
。遗憾的是VVM不支持标签,所以你必须在操作数中使用正确的数字地址。当程序还在构建中,这些地址可能会随着你添加更多的代码而改变时,这可能是一个痛苦。出于这个原因,我建议在代码块之间留一些间隙,这样当你编辑代码时,这些跳转到的地址可以保持稳定。
代码:
字符串
备注:
最后一个
dat 000
只是为了强调这个内存地址(91)是由程序使用的,并且应该有值0。这是默认值,所以没有必要严格包含它。在程序开始时,结果的初始值(地址97)也被假定为0。这是一个稍微不同的情况,因为这个结果将被程序更新。但是当程序重新加载时,所有内存首先被清除到000,这样我们就可以假定结果在每次运行时都以0开始。
但是,在VVM中的执行菜单中有一个名为 * 重新启动的选项?*.默认情况下它是开着的。如果你关闭它,并在程序运行至少一次后重新启动程序,那么就不会重新加载,所以内存将保持在前一次运行后的状态。这意味着地址97处的结果在大多数情况下不会为0。因此,新的运行将把新的产品添加到结果中,可能会给出一个令人惊讶的结果--这取决于您在这种情况下期望发生什么。
如果你希望每次运行都以结果的值零开始,即使上面提到的选项被关闭,那么在程序开始时显式地初始化结果,在最顶部插入这两条指令:
型