SUBLEQSubleq is a simple one instruction language (form of OISC). Its specifications were taken from Clive Gifford page (http://eigenratios.blogspot.com/). Each subleq instruction has 3 operands:A B C which are memory addresses. Execution of one instruction A B C subtracts the value of memory in A from the content of memory in B. If value after subtraction in B less or equal to zero, then execution jumps to the address C; otherwise to the next instruction. For example, in 3 4 6 7 7 7 3 4 0 first instruction subtracts 7 (address 3) from 7 (address 4). The result in address 4 is 0, so goto 6. On address 6 is the instruction 3 4 0 which again substracts 7 from now 0 and jumps back to 0. Here is a sequence of execution (A and B are shown after subtraction) 0: 3 4 6 A=7 B=0 6: 3 4 0 A=7 B=-7 0: 3 4 6 A=7 B=-14 6: 3 4 0 A=7 B=-21 0: 3 4 6 A=7 B=-28 ... It is not convinient to use numbers as addresses so we can replace them with labels or names: X Y 6 X:7 Y:7 7 X Y 0 Then a small convertor sqasm.cpp (download from the top of the page) would build the program above: > sqasm < file.sq > file.out > sqrun -trace file.out If we want a program to produce a result - kind of output, then we ahve to make a convention that there are well defined memory addresses which take some special functions when used. Let us have a look at this "Hi" program First line "Hi OUT" subtracts ASCII value 'H' from OUT register. We specify later that OUT register is a special register and the action is to print ASCII character of value 'H' (72). Operand C is missed, but our assembler is smart enough to assume that C is the next instruction. The next instruction is the same but writes 'i' (105) to OUT. The following instruction is an unconditional jump to a negative address, which means HALT. This subtracts the memory cell 0 from the same memory cell. The address of that memory in not important since the program stops here. The next line ". Hi: -'H' (-'i')" is data which is used by a program. Dot signifies that the command is not an instruction - it does not have necessary 3 operands. We need it to distinguish from the 2 operand command when 3rd implicitly implied. For example: the command "A:A B:B" on address 100 will be translated into "100 101 103" (103=100+3) and ".A:A B:B" into "100 101". The register OUT is not resolved on assembly stage. But we can tell the emulator to use this unresolved symbol as a special address. For example, assign -1 to it and print the value of operand A whenever instruction uses -1 as operand B. Another more complex example of "Hello world!" program The logic of this program is to output one symbol at a time pointed by a pointer p and incrementing it every iteration. The line . H: "Hello world!\n" E:E is the same as . H: 'H' 'e' 'l' 'l' 'o' ' ' 'w' 'o' 'r' 'l' 'd' '!' '\n' E:E The pointer is initialized with the label 'H' and checked for achieving the label 'E'. One complex part of the program is printing a value stored at the address stored in p (dereferencing). And another complex part of the program is a check when p==E. You have noticed that the symbol '#' makes comment. Another simplification to the syntax is semicolon ';' separating one instruction from another. Another simplification is implicit B operand, which means B=A. And yet another simplification is '?' symbol specifying the next address (this+1). For example, "A;" is the same as "A A" which is the same as "A A ?", because the default C operand is the next instruction and the address of the next instruction is the same as the address of C operand +1. The code "?; ? ? ?; ?" is translated into 1 1 3 4 5 6 7 7 9 Clive Gifford wrote self-interpreter in Subleq http://eigenratios.blogspot.com/2006/09/mark-ii-oisc-self-interpreter.html Below is a Clive's self-interpreter in this syntax. One modification was made to take into account a special OUT register, i.e. self-interpreter shifting memory address space of iterpreted program should not shift address of the special register. Here is intermediate self-interpreter code with Clive's comments. How to run self-interpreter> sqasm < siout.sq > si> sqasm < hw3.sq > hw3 > sqrun hw3 Hello world! > sqrun si hw3 Hello world! > sqrun si si hw3 Hello world! > sqrun si si si hw3 Hello world! Very slowly Comments
Syntactic sugar
Other resources
|