start: ## [A1] = [PC] # subleq A1 A1 # subleq PC ZERO # subleq ZERO A1 # subleq ZERO ZERO a1; pc zero; zero a1; zero ## Code below (after modification from above) is equivalent to [A] = [[PC]] # subleq A A #A1: data 0 # data ZERO # data A2 #A2: subleq ZERO A # subleq ZERO ZERO a; a1:0 zero a2; a2:zero a; zero ## [A] = [A] + [LEN] # subleq NEGL A negl a; ## [PC] = [PC] + 1 # subleq NEG1 PC neg1 pc; ## [B1] = [PC] # subleq B1 B1 # subleq PC ZERO # subleq ZERO B1 # subleq ZERO ZERO b1; pc zero; zero b1; zero; ## Code below (after modification from above) is equivalent to [B] = [[PC] + 1] # subleq B B #B1: data 0 # data ZERO # data B2 #B2: subleq ZERO B # subleq ZERO ZERO b; b1:0 zero b2; b2:zero b; zero; ## [B] = [B] + [LEN] # subleq NEGL B negl b; ## We have to copy [C] now, just in case the emulated subtraction modifies [[PC] + 2]. ## [PC] = [PC] + 1 # subleq NEG1 PC neg1 pc ## [C1] = [PC] # subleq C1 C1 # subleq PC ZERO # subleq ZERO C1 # subleq ZERO ZERO c1; pc zero; zero c1; zero; ## Code below (after modification from above) is equivalent to [C] = [[PC] + 2] # subleq C C #C1: data 0 # data ZERO # data C2 #C2: subleq ZERO C # subleq ZERO ZERO c; c1:0 zero c2; c2:zero c; zero; ## [[B]] = [[B]] - [[A]]; ## if [[B]] <= 0 goto LEQZ # ## Earlier code referring to addresses A and B has modified the next ## couple of words to create the equivalent of "subleq [A] [B] LEQZ" ## This is where we're "emulating" the subtraction... #A: data 0 #B: data 0 # data LEQZ a:0 b:0 leqz; ## [PC] += 1 # subleq NEG1 PC # subleq ZERO ZERO START neg1 pc; zero zero start; ## We come to address LEQZ when the emulated subleq is going to take ## the branch to the emulated address C. #LEQZ: leqz: ## First save the "raw" new PC ## [PC] = [C] # subleq PC PC # subleq C ZERO # subleq ZERO PC # subleq ZERO ZERO pc; c zero; zero pc; zero ## Check if [C] is less than zero. Halt if it is. ## We don't care about changing [C] as we've already copied the value to [PC] above. # subleq NEG1 C -1 neg1 c (-1); # I had to change this to avoid (c-1) meaning ! ## [PC] = [PC] + [LEN] # subleq NEGL PC negl pc; ## Go back to the start of the loop ready for the next instruction # subleq ZERO ZERO START zero zero start; #NEGL: data -119 # make this == -PROG (my assembler is too primitive!) #NEG1: data -1 #ZERO: data 0 #C: data 0 #PC: data PROG . negl:-(pc+1) neg1:-1 zero:0 c:0 pc:PROG # PROG is same as pc+1 # Code for the program to be interpreted must start at the PROG address... PROG: