Command LOOP has actual name: "декремент и пропуск"
Here you will find at least 3 ways how to break the loop
command
When used with direct load like:
loop #75
Loop will override itself with direct load content decremented and transfer control dependent on payload.
Thus if positive number (e.g. 0x75
) is provided as direct load, loop will transfer control to next command as if value in memory cell was positive.
And if payload is negative (e.g. 0xF5
) loop will behave like with negative value in memory cell i.e. jump over next command.
(Positive payload) Before execution:
-> 8F75
0700
0100
After:
0074
-> 0700
0100
(Negative payload) Before execution:
-> 8FF5
0700
0100
After execution:
FFF5 ; sign is bit extended, therefore you see FFF5 instead of 00F5
0700
-> 0100
Note: other addressing modes should work as expected
This addressing mode will not break loop
command if used as below:
org 0x10
word 0x5 ; <- operand
POINTER: word 0x10 ; <- address
loop (POINTER)+ ; <- autoIncrement
inc
hlt
-
Increment address and place it into
Data Register
-
Store
Data Register
content (i.e. incremented address) toPOINTER
(0x10 -> 0x11
) -
Decrement address stored in
Data Register
(DR
for short) back (0x11 -> 0x10
). Notice, thatDR
has not been cleared cleared after address increment, so address remains in register -
loop
decrements operand0x5
(located at address stored inDR
i.e.0x10
). (0x5
->0x4
)
Infinite loop DOES NOT happen because loop
performs decrement on operand and NOT on the address.
But wait! What... What if address and operand were the same essence. So... Here it is:
org 0x10
POINTER: word 0x10 ; notice pointer points to itself
LP: loop (POINTER)+
jump LP
hlt
Please! Don't run it as this will break universe to irrecoverable state!
So that's how we trigger infinite loop.
0x10 -> 0x11 -> 0x10
and so on.
Notice that increment happens first, because address increment belongs to address fetch phase. In turn, operand decrement happens during Execution phase. Address fetch precedes Execution.
If value in memory cell is equal to 0x8000
or 0x8001
then loop will NOT jump! Due to how loop
performs checks, Internal overflow occurs with these values.