Observed
The multiply loop in src/multiplyTwoNumbers.asm (lines 13-17) places its body before its test:
MULTIPLY:
AND R0, R0 #0 ; clear R0
AGAIN ADD R0, R0, R1 ; add num1 to R0
ADD R2, R2, #-1 ; decrement R2
BRp AGAIN ; if more to add, jump to again
ADD R0, R0, R1 executes unconditionally before BRp is ever evaluated. The loop is a do-while, so the accumulate is guaranteed to run at least once regardless of what R2 holds on entry.
Expected consequence
For R2 = 0 the accumulate runs once and R2 is decremented to -1, so BRp falls through and R0 is left holding R1 rather than 0. A negative R2 has the same shape. Only R2 >= 1 is expected to produce a correct product.
This consequence is UNVERIFIED. No LC-3 simulator is installed in the environment this issue was filed from (which lc3as lc3sim lc3convert lc3tools complx found nothing), so the program was not run with R2 = 0 and no register dump was produced. The reasoning above is a hand trace, which is an argument and not evidence. What is verified directly from the source is the loop's structure: the body precedes the test.
Reachability
The committed program hardcodes R2 = 6 in the TESTCODE: block, so this path cannot be reached as the file stands. It becomes reachable the moment the caller-supplied-operand contract is honored — see #2, which must be settled first.
Suggested fix
The loop is guarded with a test before the first accumulate, so that a zero or negative count skips the body entirely. Verification requires simulator runs at R2 = 0, R2 = 1, and a negative R2, with the register dump from each pasted into the pull request. Any fix pushed without those runs is unverified.
This issue body was drafted during a Gardener session (https://github.com/Stephenson-Software/gardener).
drafted by Claude on behalf of Daniel Stephenson
Observed
The multiply loop in
src/multiplyTwoNumbers.asm(lines 13-17) places its body before its test:ADD R0, R0, R1executes unconditionally beforeBRpis ever evaluated. The loop is a do-while, so the accumulate is guaranteed to run at least once regardless of what R2 holds on entry.Expected consequence
For R2 = 0 the accumulate runs once and R2 is decremented to -1, so
BRpfalls through and R0 is left holding R1 rather than 0. A negative R2 has the same shape. Only R2 >= 1 is expected to produce a correct product.This consequence is UNVERIFIED. No LC-3 simulator is installed in the environment this issue was filed from (
which lc3as lc3sim lc3convert lc3tools complxfound nothing), so the program was not run with R2 = 0 and no register dump was produced. The reasoning above is a hand trace, which is an argument and not evidence. What is verified directly from the source is the loop's structure: the body precedes the test.Reachability
The committed program hardcodes R2 = 6 in the
TESTCODE:block, so this path cannot be reached as the file stands. It becomes reachable the moment the caller-supplied-operand contract is honored — see #2, which must be settled first.Suggested fix
The loop is guarded with a test before the first accumulate, so that a zero or negative count skips the body entirely. Verification requires simulator runs at R2 = 0, R2 = 1, and a negative R2, with the register dump from each pasted into the pull request. Any fix pushed without those runs is unverified.
This issue body was drafted during a Gardener session (https://github.com/Stephenson-Software/gardener).
drafted by Claude on behalf of Daniel Stephenson