Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

HÁÓÞÅÔ One-Command CPU ÓÏ ÓÔpÅÌËÏÊ ðÉpÓÁ.

1 view
Skip to first unread message

Serguey Zefirov

unread,
Feb 28, 1997, 3:00:00 AM2/28/97
to

Zdorovenki bulji,(Hi! in other words) All!


-------------------------------8<------------------------------------
# This is a shell archive. Remove anything before this line,
# then unpack it by saving it in a file and typing "sh file".
#
# Wrapped by Ross Cunniff <cun...@fc.hp.com> on Tue Sep 20 15:44:59 1994
#
# This archive contains:
# Makefile README macros interp
# oisc.c fact.x indirect.x print.x
# print1.x rfact.x
#
# Error checking via wc(1) will be performed.

LANG=""; export LANG
PATH=/bin:/usr/bin:$PATH; export PATH

echo x - Makefile

cat >Makefile <<'@EOF'

# This Makefile is so simple as to be pathetic

CC=c89
CFLAGS=-g

oisc: oisc.c
$(CC) $(CFLAGS) oisc.c -o oisc
@EOF
set `wc -lwc <Makefile`
if test $1$2$3 != 719111
then
echo ERROR: wc results of Makefile are $* should be 7 19 111
fi

chmod 644 Makefile

echo x - README

cat >README <<'@EOF'

You've heard of RISC (Reduced Instruction Set Computer) and CISC
(Complex Instruction Set Computer); now, have a OISC! OISC models a One
Instruction Set Computer. That is to say, it models a computer that has
only one instruction. The instruction? Subtract and jump if negative.
The instruction has three operands: X, Y, and Z. X and Y are the
addresses operands; Z is the destination address. Since there's only
one instruction, we don't actually need an opcode. So, here's an
example of an OISC instruction:

0 1 2

Basically, it says "take the contents at address 0, subtract the
contents of address one from it, and if that is negative, jump to
address 2."

Believe it or not, you can write any program you can dream of with this
one instruction (and a little self-modifying code). Well, almost any
program. It lacks little things like O/S interaction. There is,
however, I/O defined. There are three special addresses:

#define WRITE 32765
#define READ 32766
#define STOP 32767

If the WRITE address is used as the destination, then the integer in
source is printed out. Well, almost. The negative of the source is
printed out, since the WRITE address always keeps a value of zero, and
the source is subtracted from the destination before storing it. The
branch-if- negative then proceeds as expected.

If the READ address is used as the source, then an integer is read from
stdin to be used as the real source. It's then subtracted from the
destination, and the branch-if-negative proceeds as expected.

If the STOP address is used as the branch target (and the branch is
taken), then OISC terminates.

Here's a simple OISC program, which reads a number and then prints it
out. The text following a semicolon is a comment.

9 32766 3 ; Address 0: Read a number, subtract it from
; address 9. Go to 3 if negative.
32765 9 6 ; Address 3: Print address 9 out. Go to
; 6 if negative
10 11 32767 ; Address 6: Subtract conts of address 11 from
; address 10 Go to STOP if negative (which it
; will, since address 11 contains 0, and
; address 10 contains -1).
0 ; Address 9 - storage for the number
-1 ; Address 10 - negative one for unconditional branch
0 ; Address 11 - zero for unconditional branch

Of course, you may be skeptical that you can write *ANY* program with
this system. Well, the few sample programs will change your mind. They
are:

macros CPP macros which define lotsa psuedo-ASM
instructions using only OISC
interp A shell script to interpret OISC programs
by calling CPP on them first
print.x The above program
print1.x The below program
fact.x Computes the factorial of a number
indirect.x Demonstrates address calcuations
rfact.x Recursively (!) computes the factorial of a number.

To understand these programs, you'll have to understand a little of the
OISC syntax. As I mentioned before, the basic instruction sequence is:

X Y Z

OISC lets you assign symbolic names to addresses, using classical
assembly language syntax, like this:

NEG1: -1 ; This address contains -1 initially

OISC predefines the READ, WRITE, and STOP address symbols, so you don't
have to remember numbers like 32765.

OISC also has a separate TEXT and DATA segment. To put stuff in the
TEXT segment, put the line:

TEXT:

in your file. To put stuff in the DATA segment, put the line:

DATA:

in your file. Finally, for convenience in creating macros, there's a
shorthand for the current address. That is the dot '.'. You can also
say 'current address plus 3 words', for example, by saying '.+3'. Note
that '.' refers to the CURRENT SUBADDRESS (each instruction takes 3
words...). Also note that OISC is word-addressible.

So here's the simple I/O example from above, recoded with symbols and
dot notation (this example is in print1.x):

TEXT:
NUM READ .+1
WRITE NUM .+1
NEG1 ZERO STOP
DATA:
NUM: 0 ; Storage for the number
NEG1: -1 ; The number negative one
ZERO: 0 ; The number zero

So, thus ends this completely inadequate and incomprehensible
documentation. Enjoy!

Ross Cunniff
Hewlett-Packard Graphics Software Lab
cun...@fc.hp.com
DISCLAIMER: HP would be bankrupt if I worked in the CPU design division...
@EOF
exit 0
-------------------------------8<------------------------------------
Вот.
Где взял - не помню. Кидать сюда я не буду, это не по теме (там на C написано),
мылом отсылать тоже. Идея из исходника HACKME и вышепpиведенного описания должна
быть ясна. Да в пpинципе важна только сама идея: из одной инстpукции комп
сооpудить.

:[ sz G!>U d? s:(-:) a- C--->-- !U !P !L !E W>- N++ !o K---- w$ O- M- !V PS+ Y+
PE+++ PGP t>--- 5>--- X? R- tv-->! b++ DI? D+ G- e- h+ r?(--) y ]; IMMEDIATE

... Can you understand your pussy cat? Do you know what it need?

0 new messages