Compare commits

..

37 Commits

Author SHA1 Message Date
nils polek
70dbd0253b Big int works 2024-01-18 17:17:07 +00:00
5039f95153 Revert "update"
This reverts commit dbafdbeea5.
2024-01-18 17:24:01 +01:00
dbafdbeea5 update 2024-01-18 16:21:34 +01:00
nils polek
ac57431ac4 added big int lib 2024-01-15 16:28:41 +00:00
nils polek
3935d2778b alle rechenobjekte im stack sind jetzt pointer 2024-01-15 15:32:02 +00:00
nils polek
37843d9356 Added a debug menue 2024-01-15 12:43:49 +00:00
nils polek
6cc2ff87ca Stack uses only references and equation objects 2024-01-15 11:48:21 +00:00
nils polek
f29f500d0c added some shit 2024-01-14 20:09:51 +00:00
nils polek
23e787eb5e added pushr popr 2024-01-14 17:39:11 +00:00
nils polek
94fb404c71 Added nja njc and Makefile 2024-01-14 17:11:09 +00:00
847f68bb29 fix error 2023-12-28 22:29:30 +01:00
da06afd43b update version to 8 2023-12-28 22:28:35 +01:00
9421d34756 add heap and stack args (not yet implemented) 2023-12-28 22:25:40 +01:00
Nils Polek
60bdfd7843 Added DUB 2023-12-10 00:24:17 +01:00
bdb0ce63b8 fix dfbnjkhghjdfsbg 2023-12-10 00:18:20 +01:00
dcb665f5a6 update debug 2023-12-10 00:00:59 +01:00
Nils Polek
82dc5f28cc abc 2023-12-09 23:43:33 +01:00
8be99c5244 update debug 2023-12-09 23:15:11 +01:00
742f050b24 update debug 2023-12-09 23:14:19 +01:00
14025d3b08 update debug 2023-12-09 23:12:33 +01:00
3f12378110 update debug 2023-12-09 23:11:42 +01:00
2cb94eaf76 update debug 2023-12-09 23:10:31 +01:00
9d64b87a09 update debug 2023-12-09 23:10:23 +01:00
b87ebbe841 update debug 2023-12-09 23:03:32 +01:00
829735eb8c update debug 2023-12-09 22:57:26 +01:00
44f70a1777 update debug 2023-12-09 22:51:27 +01:00
5a7338f91c update debug 2023-12-09 22:49:44 +01:00
a8999f4ec2 update debug 2023-12-09 22:43:53 +01:00
c0a5e694c0 update debug
fix call not jumping
2023-12-09 22:42:46 +01:00
Nils Polek
61a138fdee versin v 2023-12-09 22:40:18 +01:00
55af679c39 fix jump not working right 2023-12-09 22:10:02 +01:00
27400289f5 update debug 2023-12-09 22:00:13 +01:00
c0d25212af fix printProgram 2023-12-09 21:56:17 +01:00
10a6883750 update debug mode 2023-12-09 21:55:12 +01:00
Nils Polek
33a2994c29 Commit with mistake 2023-12-09 21:40:42 +01:00
Nils Polek
7390df9ee0 Aufgabe 2 Fertig 2023-12-09 20:35:15 +01:00
Nils Polek
83dae77e31 aufgabe 2 stack overflow 2023-12-09 19:45:15 +01:00
65 changed files with 3310 additions and 462 deletions

View File

@@ -3,8 +3,13 @@
# Compiler # Compiler
CC = gcc CC = gcc
# program to Run
F = prog.bin
# Compiler flags # Compiler flags
CFLAGS = -g -Wall -std=c99 -pedantic CFLAGS = -g -Wall -Ibigint/build/include
LDFLAGS = -g -Wall -Lbigint/build/lib
# Source file # Source file
SRC = njvm.c SRC = njvm.c
@@ -12,15 +17,24 @@ SRC = njvm.c
# Executable name # Executable name
TARGET = njvm TARGET = njvm
njvm.o:
$(CC) $(CFLAGS) -o njvm.o -c njvm.c
support.o:
$(CC) $(CFLAGS) -o support.o -c support.c
# Default target # Default target
all: all: njvm.o support.o
$(CC) $(CFLAGS) -o $(TARGET) $(SRC) $(CC) $(LDFLAGS) -o $(TARGET) njvm.o support.o -lbigint
# Clean up # Clean up
clean: clean:
rm -f $(OBJ) $(TARGET) rm -f $(OBJ) $(TARGET)
debug: all
./$(TARGET) --debug $(F)
run: all run: all
./$(TARGET) ./$(TARGET) $(F)
nja: ./nja/nja$(V) nja: ./nja/nja$(V)
./nja/nja$(V) $(IN) $(OUT) ./nja/nja$(V) $(IN) $(OUT)

21
SDA.c
View File

@@ -4,24 +4,23 @@
#ifndef SDA #ifndef SDA
#define SDA #define SDA
#include <stdio.h> #include <stdio.h>
#include "stackslot.c"
struct sda { struct sda {
unsigned int *sda; int *size;
int size; ObjRef *sda;
}; };
int getSDA(unsigned int offset, struct sda *sda) { ObjRef getSDA(int i, struct sda s) {
return sda->sda[offset]; return s.sda[i];
} }
void setSDA(unsigned int offset, int value, struct sda *sda) { void setSDA(int point, ObjRef val, struct sda s) {
sda->sda[offset] = value; s.sda[point] = val;
} }
void printSDA(struct sda *sda) { void printSDA(struct sda s) {
printf("SDA:\n"); for (int i = 0; i < *s.size; i++) {
for (int i = 0; i < sda->size; ++i) { printf("%i\n", *(int *)getSDA(i, s)->data);
printf("[%d] = %d\n", i, sda->sda[i]);
} }
} }

BIN
a.out Executable file

Binary file not shown.

22
bigint/Makefile Normal file
View File

@@ -0,0 +1,22 @@
#
# Makefile for big integer library and test
#
DIRS = src tst
all:
for i in $(DIRS) ; do \
$(MAKE) -C $$i install ; \
done
clean:
for i in $(DIRS) ; do \
$(MAKE) -C $$i clean ; \
done
rm -rf ./build
rm -f *~
dist: clean
(cd .. ; \
tar -cvf bigint.tar bigint ; \
gzip -f bigint.tar)

92
bigint/README Normal file
View File

@@ -0,0 +1,92 @@
The "bigint" Package
====================
1. What is it?
--------------
This package implements a multiple-precision integer arithmetic package,
i.e., a collection of functions which can calculate with integers having
arbitrarily many digits. The algorithms are taken from [D. Knuth: The
Art of Computer Programming, Vol. 2, Seminumerical Algorithms], the
implementation language is C.
2. "Multiple Precision" - how does it work?
-------------------------------------------
Each integer number is represented as an array of digits. The array
is large enough to hold the number of digits necessary to represent
the number. Each digit occupies a single byte, so the number base of
this representation is 256. Addition, subtraction, and multiplication
work as we all have learned it: perform the desired operation digit
by digit, starting from the least significant digit, and observing
any "carries" from one place to the next higher one. Division is a
little bit more complicated because there is a certain amount of
guesswork involved. Knuth gives a formal treatment of this guesswork.
3. How do I use it?
-------------------
Because every big integer may have a differently sized array to hold
its digits, these structures are dynamically allocated on the heap of
the C runtime system, and accessed by pointers. If you want to perform
an arithmetic operation on one or two big integers, you have to load
the corresponding pointers into a structure called BIP ("Big Integer
Processor"), and call the arithmetic function. When the function has
returned, the pointer to the result of the operation can be found in
another component of the BIP. The following functions are available:
int bigSgn(void); /* sign */
int bigCmp(void); /* comparison */
void bigNeg(void); /* negation */
void bigAdd(void); /* addition */
void bigSub(void); /* subtraction */
void bigMul(void); /* multiplication */
void bigDiv(void); /* division */
void bigFromInt(int n); /* conversion int --> big */
int bigToInt(void); /* conversion big --> int */
void bigRead(FILE *in); /* read a big integer */
void bigPrint(FILE *out); /* print a big integer */
void bigDump(FILE *out, BigObjRef bigObjRef); /* dump a big integer */
Some of these functions accept or return ordinary integers. For the
exact definition of each function's interface, please see the comments
in the function's source.
4. What else is needed?
-----------------------
The library tries to detect fatal errors in using its functions (e.g.,
null pointers to operands) as well as internal errors (which "cannot
happen"). In either case a user-supplied error routine is called, which
is supposed to print an error message and then to terminate the program.
The library does not attempt to manage memory. For this purpose, it
relies on a user-supplied function "void* newPrimObject(int dataSize)",
which should allocate sufficiently many bytes and return a pointer to
a created object. In addition, the library needs to access a data field
- that implements the size-as-needed cocept - within the created object,
to actualy manage the data structures that represent the values of the
integer number. For this, the following function can be used:
void * getPrimObjectDataPointer(void * obj){
ObjRef oo = ((ObjRef) (obj));
return oo->data;
}
This function must also be a user-supplied function that must be
implemented by the program that wants to use this library.
For details about these three user-supplied functions take a look in
the file "support.c" in the directory "tst".
5. What is in the directory "tst"?
----------------------------------
Well, you may have guessed it already: these are test cases for the
library. You can learn how to link against the library by inspecting
the "Makefile" for the tests, and you can find a simple implementation
of the support library.

BIN
bigint/build/bin/testbip Executable file

Binary file not shown.

View File

@@ -0,0 +1,60 @@
/*
* bigint.h -- big integer library
*/
#ifndef _BIGINT_H_
#define _BIGINT_H_
/* object representation */
typedef void* BigObjRef;
#include <stdio.h>
typedef struct {
int nd; /* number of digits; array may be bigger */
/* nd = 0 exactly when number = 0 */
unsigned char sign; /* one of BIG_NEGATIVE or BIG_POSITIVE */
/* zero always has BIG_POSITIVE here */
unsigned char digits[1]; /* the digits proper; number base is 256 */
/* LS digit first; MS digit is not zero */
} Big;
#include "support.h"
/* big integer processor registers */
typedef struct {
BigObjRef op1; /* first (or single) operand */
BigObjRef op2; /* second operand (if present) */
BigObjRef res; /* result of operation */
BigObjRef rem; /* remainder in case of division */
} BIP;
extern BIP bip; /* registers of the processor */
/* big integer processor functions */
int bigSgn(void); /* sign */
int bigCmp(void); /* comparison */
void bigNeg(void); /* negation */
void bigAdd(void); /* addition */
void bigSub(void); /* subtraction */
void bigMul(void); /* multiplication */
void bigDiv(void); /* division */
void bigFromInt(int n); /* conversion int --> big */
int bigToInt(void); /* conversion big --> int */
void bigRead(FILE *in); /* read a big integer */
void bigPrint(FILE *out); /* print a big integer */
void bigDump(FILE *out, BigObjRef bigObjRef); /* dump a big integer object */
#endif /* _BIGINT_H_ */

View File

@@ -0,0 +1,15 @@
/*
* support.h -- object representation and support functions
*/
#ifndef _SUPPORT_H_
#define _SUPPORT_H_
/* support functions */
void fatalError(char *msg); /* print a message and exit */
void * newPrimObject(int dataSize); /* create a new primitive object */
void * getPrimObjectDataPointer(void * primObject);
#endif /* _SUPPORT_H_ */

Binary file not shown.

26
bigint/src/Makefile Normal file
View File

@@ -0,0 +1,26 @@
#
# Makefile for big integer library
#
BUILD = ../build
CC = gcc
CFLAGS = -g -Wall
all: support.h bigint.h libbigint.a
install: all
mkdir -p $(BUILD)/include
cp support.h $(BUILD)/include
cp bigint.h $(BUILD)/include
mkdir -p $(BUILD)/lib
cp libbigint.a $(BUILD)/lib
libbigint.a: bigint.o
ar -crs libbigint.a bigint.o
bigint.o: bigint.c bigint.h support.h
$(CC) $(CFLAGS) -o bigint.o -c bigint.c
clean:
rm -f *~ bigint.o libbigint.a

987
bigint/src/bigint.c Normal file
View File

@@ -0,0 +1,987 @@
/*
* bigint.c -- big integer library
*/
#include <stdio.h>
#include <ctype.h>
#include "bigint.h"
/**************************************************************/
/* debugging */
#define DIV_CHK_01 0
#define DIV_CHK_02 0
#define DIV_CHK_03 0
#define DIV_CHK_04 0
#define DIV_CHK_05 0
#define DIV_CHK_06 0
#define DIV_CHK_07 0
#define DIV_CHK_08 0
#define DIV_CHK_09 0
#define DIV_CHK_10 0
#define DIV_CHK_11 0
/**************************************************************/
/* big integer representation */
#define BIG_NEGATIVE ((unsigned char) 0)
#define BIG_POSITIVE ((unsigned char) 1)
#define BIG_PTR(bigObjRef) ((Big *) (getPrimObjectDataPointer(bigObjRef)))
#define GET_ND(bigObjRef) (BIG_PTR(bigObjRef)->nd)
#define SET_ND(bigObjRef, val) (BIG_PTR(bigObjRef)->nd = (val))
#define GET_SIGN(bigObjRef) (BIG_PTR(bigObjRef)->sign)
#define SET_SIGN(bigObjRef, val) (BIG_PTR(bigObjRef)->sign = (val))
#define GET_DIGIT(bigObjRef, i) (BIG_PTR(bigObjRef)->digits[i])
#define SET_DIGIT(bigObjRef, i, val) (BIG_PTR(bigObjRef)->digits[i] = (val))
/**************************************************************/
/* global data */
/*
* registers of the big integer processor
*/
BIP bip = {
NULL, /* op1 */
NULL, /* op2 */
NULL, /* res */
NULL, /* rem */
};
/**************************************************************/
/*
* construct a new big integer object
*
* number of digits is given by parameter
* a reference to a proper object is returned
* but no component of the big integer is set
*
* ATTENTION: All object references stored in
* places other than the bip registers may become
* invalid as soon as this function is called!
*/
static BigObjRef newBig(int nd) {
int dataSize;
BigObjRef bigObjRef;
dataSize = sizeof(int) + 1 + nd;
bigObjRef = newPrimObject(dataSize);
return bigObjRef;
}
/**************************************************************/
/* big integer unsigned arithmetic */
/*
* exchange bip.op1 and bip.op2
*/
static void bigXchg(void) {
BigObjRef tmp;
tmp = bip.op1;
bip.op1 = bip.op2;
bip.op2 = tmp;
}
/*
* big integer unsigned comparison
*
* operands in bip.op1 and bip.op2
* result is < 0, = 0, or > 0 if and only if the
* same relation holds for bip.op1 and bip.op2
*/
static int bigUcmp(void) {
int nd1;
int nd2;
int diff;
/* compare sizes */
nd1 = GET_ND(bip.op1);
nd2 = GET_ND(bip.op2);
if (nd1 != nd2) {
/* sizes are different: we know the bigger number */
return nd1 - nd2;
}
/* sizes are equal: we must look at the digits */
while (nd1--) {
diff = (int) GET_DIGIT(bip.op1, nd1) -
(int) GET_DIGIT(bip.op2, nd1);
if (diff != 0) {
return diff;
}
}
/* the numbers are equal */
return 0;
}
/*
* big integer unsigned addition
*
* operands in bip.op1 and bip.op2
* result in bip.res
*/
static void bigUadd(void) {
int nd1;
int nd2;
int i;
unsigned short carry;
unsigned short aux;
int xchgFlag;
/* make sure op1 has at least as many digits as op2 */
nd1 = GET_ND(bip.op1);
nd2 = GET_ND(bip.op2);
if (nd1 < nd2) {
/* exchange operands */
bigXchg();
i = nd1;
nd1 = nd2;
nd2 = i;
xchgFlag = 1;
} else {
/* don't exchange operands */
xchgFlag = 0;
}
/* allocate result */
bip.res = newBig(nd1 + 1);
/* copy op2 to result */
for (i = 0; i < nd2; i++) {
SET_DIGIT(bip.res, i, GET_DIGIT(bip.op2, i));
}
/* fill result with 0 up to size of op1 */
for (; i < nd1; i++) {
SET_DIGIT(bip.res, i, 0);
}
/* res = op1 + res */
carry = 0x00;
for (i = 0; i < nd1; i++) {
aux = (unsigned short) GET_DIGIT(bip.op1, i) +
(unsigned short) GET_DIGIT(bip.res, i) +
carry;
SET_DIGIT(bip.res, i, aux & 0xFF);
carry = aux >> 8;
}
SET_DIGIT(bip.res, i, carry);
/* determine actual size of result */
i = nd1 + 1;
while (--i >= 0 && GET_DIGIT(bip.res, i) == 0) ;
SET_ND(bip.res, i + 1);
/* restore operands */
if (xchgFlag) {
bigXchg();
}
}
/*
* big integer unsigned subtraction
*
* operands in bip.op1 and bip.op2
* result in bip.res, must not be negative
*/
static void bigUsub(void) {
int nd1;
int nd2;
int i;
unsigned short carry;
unsigned short aux;
/* op1 must have at least as many digits as op2 */
nd1 = GET_ND(bip.op1);
nd2 = GET_ND(bip.op2);
if (nd1 < nd2) {
/* unsigned subtraction would yield negative result */
fatalError("internal library error #1 - THIS SHOULD NEVER HAPPEN!");
}
/* allocate result */
bip.res = newBig(nd1);
/* copy op2 to result */
for (i = 0; i < nd2; i++) {
SET_DIGIT(bip.res, i, GET_DIGIT(bip.op2, i));
}
/* fill result with 0 up to size of op1 */
for (; i < nd1; i++) {
SET_DIGIT(bip.res, i, 0);
}
/* res = op1 - res */
carry = 0x01;
for (i = 0; i < nd1; i++) {
aux = (unsigned short) GET_DIGIT(bip.op1, i) -
(unsigned short) GET_DIGIT(bip.res, i) +
carry + 0xFF;
SET_DIGIT(bip.res, i, aux & 0xFF);
carry = aux >> 8;
}
if (carry != 0x01) {
/* unsigned subtraction would yield negative result */
fatalError("internal library error #2 - THIS SHOULD NEVER HAPPEN!");
}
/* determine actual size of result */
i = nd1;
while (--i >= 0 && GET_DIGIT(bip.res, i) == 0) ;
SET_ND(bip.res, i + 1);
}
/*
* big integer unsigned multiplication
*
* operands in bip.op1 and bip.op2
* result in bip.res
*/
static void bigUmul(void) {
int nd1;
int nd2;
int i, j, k;
unsigned short carry;
unsigned short aux;
/* get sizes of operands */
nd1 = GET_ND(bip.op1);
nd2 = GET_ND(bip.op2);
/* allocate result */
bip.res = newBig(nd1 + nd2);
/* reset lower nd1 digits of result */
for (i = 0; i < nd1; i++) {
SET_DIGIT(bip.res, i, 0);
}
/* res = op1 * op2 */
for (j = 0; j < nd2; j++) {
carry = 0x00;
for (k = j, i = 0; i < nd1; k++, i++) {
aux = (unsigned short) GET_DIGIT(bip.op1, i) *
(unsigned short) GET_DIGIT(bip.op2, j) +
(unsigned short) GET_DIGIT(bip.res, k) +
carry;
SET_DIGIT(bip.res, k, aux & 0xFF);
carry = aux >> 8;
}
SET_DIGIT(bip.res, k, carry);
}
/* determine actual size of result */
i = nd1 + nd2;
while (--i >= 0 && GET_DIGIT(bip.res, i) == 0) ;
SET_ND(bip.res, i + 1);
}
/*
* big integer unsigned division by single digit divisor
*
* dividend in bip.rem, divisor in parameter
* quotient in bip.rem, remainder is returned
*/
static unsigned char bigUdiv1(unsigned char divisor) {
BigObjRef tmp;
int nd;
int i;
unsigned short d, r;
unsigned short aux;
/* get size of dividend */
nd = GET_ND(bip.rem);
/* check for division by zero */
d = (unsigned short) divisor;
if (d == 0) {
fatalError("internal library error #3 - THIS SHOULD NEVER HAPPEN!");
}
/* allocate result */
tmp = newBig(nd);
/* tmp = dividend / divisor, r = dividend % divisor */
r = 0;
for (i = nd - 1; i >= 0; i--) {
aux = (r << 8) | (unsigned short) GET_DIGIT(bip.rem, i);
SET_DIGIT(tmp, i, aux / d);
r = aux % d;
}
/* determine actual size of quotient */
i = nd;
while (--i >= 0 && GET_DIGIT(tmp, i) == 0) ;
SET_ND(tmp, i + 1);
/* store quotient */
bip.rem = tmp;
/* return remainder */
return (unsigned char) r;
}
/*
* big integer unsigned division
*
* dividend in bip.op1, divisor in bip.op2
* quotient in bip.res, remainder in bip.rem
*/
static void bigUdiv(void) {
BigObjRef tmp;
int nd1;
int nd2;
int nd3;
int i, j, k, l;
unsigned char r;
unsigned short scale;
unsigned short carry;
unsigned short aux;
unsigned short qhat;
unsigned short v1, v2;
unsigned short uj0, uj1, uj2, two;
/* get sizes of operands */
nd1 = GET_ND(bip.op1);
nd2 = GET_ND(bip.op2);
/* check for division by zero */
if (nd2 == 0) {
fatalError("division by zero");
}
/* check for small dividend */
if (bigUcmp() < 0) {
/* res = 0 */
bip.res = newBig(0);
SET_ND(bip.res, 0);
/* rem = op1; BUT THIS HAS TO BE A COPY! */
bip.rem = newBig(nd1);
for (i = 0; i < nd1; i++) {
SET_DIGIT(bip.rem, i, GET_DIGIT(bip.op1, i));
}
SET_ND(bip.rem, nd1);
return;
}
/* check for single digit divisor */
if (nd2 == 1) {
/* yes - use simple division by single digit divisor */
bip.rem = bip.op1;
r = bigUdiv1(GET_DIGIT(bip.op2, 0));
bip.res = bip.rem;
if (r == 0) {
bip.rem = newBig(0);
SET_ND(bip.rem, 0);
} else {
bip.rem = newBig(1);
SET_ND(bip.rem, 1);
SET_DIGIT(bip.rem, 0, r);
}
return;
}
/*
* now for the general case
*/
#if DIV_CHK_01
printf("div_chk #01: division, general case\n");
printf(" dividend = ");
bigDump(stdout, bip.op1);
printf("\n");
printf(" divisor = ");
bigDump(stdout, bip.op2);
printf("\n");
#endif
/* determine scale factor for normalization */
scale = (unsigned short) 256 /
((unsigned short) GET_DIGIT(bip.op2, nd2 - 1) + 1);
#if DIV_CHK_02
printf("div_chk #02: scale factor = %02X\n", scale);
#endif
/* normalize dividend, result is in bip.rem */
bip.rem = newBig(nd1 + 1);
carry = 0x00;
for (i = 0; i < nd1; i++) {
aux = (unsigned short) GET_DIGIT(bip.op1, i) * scale +
carry;
SET_DIGIT(bip.rem, i, aux & 0xFF);
carry = aux >> 8;
}
SET_DIGIT(bip.rem, i, carry);
SET_ND(bip.rem, nd1 + 1);
#if DIV_CHK_03
printf("div_chk #03: normalized dividend = ");
bigDump(stdout, bip.rem);
printf("\n");
#endif
/* normalize divisor, result is in bip.res */
bip.res = newBig(nd2);
carry = 0x00;
for (i = 0; i < nd2; i++) {
aux = (unsigned short) GET_DIGIT(bip.op2, i) * scale +
carry;
SET_DIGIT(bip.res, i, aux & 0xFF);
carry = aux >> 8;
}
if (carry != 0x00) {
/* overflow in divisor normalization */
fatalError("internal library error #4 - THIS SHOULD NEVER HAPPEN!");
}
SET_ND(bip.res, nd2);
#if DIV_CHK_04
printf("div_chk #04: normalized divisor = ");
bigDump(stdout, bip.res);
printf("\n");
#endif
/* allocate quotient */
nd3 = nd1 - nd2 + 1;
tmp = newBig(nd3);
/* extract the two most significand digits of divisor */
v1 = (unsigned short) GET_DIGIT(bip.res, nd2 - 1);
v2 = (unsigned short) GET_DIGIT(bip.res, nd2 - 2);
/* loop on digits of dividend and compute digits of quotient */
/* j is index into dividend, k is index into quotient */
for (j = nd1, k = nd3 - 1; k >= 0; j--, k--) {
#if DIV_CHK_05
printf("div_chk #05: j = %d, k = %d\n", j, k);
#endif
/* calculate qhat */
uj0 = (unsigned short) GET_DIGIT(bip.rem, j);
uj1 = (unsigned short) GET_DIGIT(bip.rem, j - 1);
uj2 = (unsigned short) GET_DIGIT(bip.rem, j - 2);
two = (uj0 << 8) | uj1;
if (uj0 == v1) {
qhat = (unsigned short) 255;
#if DIV_CHK_06
printf("div_chk #06a: qhat = %02X\n", qhat);
#endif
} else {
qhat = two / v1;
#if DIV_CHK_06
printf("div_chk #06b: qhat = %02X\n", qhat);
#endif
}
while (qhat * v2 > (((two - qhat * v1) << 8) | uj2)) {
qhat--;
#if DIV_CHK_07
printf("div_chk #07: qhat decremented, is now %02X\n", qhat);
#endif
}
/* multiply and subtract */
/* l is index into dividend, i is index into divisor */
carry = 0xFF;
for (l = j - nd2, i = 0; i < nd2; l++, i++) {
aux = (unsigned short) GET_DIGIT(bip.rem, l) -
(unsigned short) GET_DIGIT(bip.res, i) * qhat +
carry + 0xFE01;
SET_DIGIT(bip.rem, l, aux & 0xFF);
carry = aux >> 8;
}
aux = (unsigned short) GET_DIGIT(bip.rem, l) +
carry + 0xFE01;
SET_DIGIT(bip.rem, l, aux & 0xFF);
carry = aux >> 8;
#if DIV_CHK_08
printf("div_chk #08: remainder = ");
bigDump(stdout, bip.rem);
printf("\n");
#endif
/* test remainder and possibly add back */
if (carry != 0xFF) {
/* qhat is one too large */
qhat--;
#if DIV_CHK_09
printf("div_chk #09: qhat final correction, is now %02X\n", qhat);
#endif
/* add back */
/* l is index into dividend, i is index into divisor */
carry = 0x00;
for (l = j - nd2, i = 0; i < nd2; l++, i++) {
aux = (unsigned short) GET_DIGIT(bip.rem, l) +
(unsigned short) GET_DIGIT(bip.res, i) +
carry;
SET_DIGIT(bip.rem, l, aux & 0xFF);
carry = aux >> 8;
}
aux = (unsigned short) GET_DIGIT(bip.rem, l) +
carry;
SET_DIGIT(bip.rem, l, aux & 0xFF);
carry = aux >> 8;
if (carry != 0x01) {
/* missing carry in add-back sum */
fatalError("internal library error #5 - THIS SHOULD NEVER HAPPEN!");
}
#if DIV_CHK_10
printf("div_chk #10: remainder = ");
bigDump(stdout, bip.rem);
printf("\n");
#endif
}
/* store quotient digit */
SET_DIGIT(tmp, k, qhat);
#if DIV_CHK_11
printf("div_chk #11: quotient digit = %02X\n", qhat);
#endif
}
/* finish quotient */
i = nd3;
while (--i >= 0 && GET_DIGIT(tmp, i) == 0) ;
SET_ND(tmp, i + 1);
bip.res = tmp;
/* finish and unnormalize remainder */
i = nd1 + 1;
while (--i >= 0 && GET_DIGIT(bip.rem, i) == 0) ;
SET_ND(bip.rem, i + 1);
r = bigUdiv1(scale);
if (r != 0) {
/* non-zero remainder in unnormalization */
fatalError("internal library error #6 - THIS SHOULD NEVER HAPPEN!");
}
}
/**************************************************************/
/* nil reference exception */
static void nilRefException(void) {
fatalError("big integer library detected illegal nil reference");
}
/**************************************************************/
/* big integer arithmetic */
/*
* big integer sign
*
* operand in bip.op1
* result is < 0, = 0, or > 0 if and only if
* the same relation holds for bip.op1
*/
int bigSgn(void) {
if (bip.op1 == NULL) {
nilRefException();
}
if (GET_ND(bip.op1) == 0) {
return 0;
}
if (GET_SIGN(bip.op1) == BIG_POSITIVE) {
return 1;
} else {
return -1;
}
}
/*
* big integer comparison
*
* operands in bip.op1 and bip.op2
* result is < 0, = 0, or > 0 if and only if the
* same relation holds for bip.op1 and bip.op2
*/
int bigCmp(void) {
if (bip.op1 == NULL ||
bip.op2 == NULL) {
nilRefException();
}
if (GET_SIGN(bip.op1) == BIG_POSITIVE) {
if (GET_SIGN(bip.op2) == BIG_POSITIVE) {
/* op1 >= 0 and op2 >= 0 */
return bigUcmp();
} else {
/* op1 >= 0 and op2 < 0 */
return 1;
}
} else {
if (GET_SIGN(bip.op2) == BIG_POSITIVE) {
/* op1 < 0 and op2 >= 0 */
return -1;
} else {
/* op1 < 0 and op2 < 0 */
return -bigUcmp();
}
}
}
/*
* big integer negation
*
* operand in bip.op1
* result in bip.res
*/
void bigNeg(void) {
int nd;
int i;
if (bip.op1 == NULL) {
nilRefException();
}
/* make copy of operand */
nd = GET_ND(bip.op1);
bip.res = newBig(nd);
for (i = 0; i < nd; i++) {
SET_DIGIT(bip.res, i, GET_DIGIT(bip.op1, i));
}
SET_ND(bip.res, nd);
/* store inverted sign */
if (GET_SIGN(bip.op1) == BIG_NEGATIVE || nd == 0) {
SET_SIGN(bip.res, BIG_POSITIVE);
} else {
SET_SIGN(bip.res, BIG_NEGATIVE);
}
}
/*
* big integer addition
*
* operands in bip.op1 and bip.op2
* result in bip.res
*/
void bigAdd(void) {
if (bip.op1 == NULL ||
bip.op2 == NULL) {
nilRefException();
}
if (GET_SIGN(bip.op1) == BIG_POSITIVE) {
if (GET_SIGN(bip.op2) == BIG_POSITIVE) {
/* op1 >= 0 and op2 >= 0 */
bigUadd();
SET_SIGN(bip.res, BIG_POSITIVE);
} else {
/* op1 >= 0 and op2 < 0 */
if (bigUcmp() >= 0) {
/* |op1| >= |op2| */
bigUsub();
SET_SIGN(bip.res, BIG_POSITIVE);
} else {
/* |op1| < |op2| */
bigXchg();
bigUsub();
SET_SIGN(bip.res, BIG_NEGATIVE);
bigXchg();
}
}
} else {
if (GET_SIGN(bip.op2) == BIG_POSITIVE) {
/* op1 < 0 and op2 >= 0 */
if (bigUcmp() <= 0) {
/* |op1| <= |op2| */
bigXchg();
bigUsub();
SET_SIGN(bip.res, BIG_POSITIVE);
bigXchg();
} else {
/* |op1| > |op2| */
bigUsub();
SET_SIGN(bip.res, BIG_NEGATIVE);
}
} else {
/* op1 < 0 and op2 < 0 */
bigUadd();
SET_SIGN(bip.res, BIG_NEGATIVE);
}
}
}
/*
* big integer subtraction
*
* operands in bip.op1 and bip.op2
* result in bip.res
*/
void bigSub(void) {
if (bip.op1 == NULL ||
bip.op2 == NULL) {
nilRefException();
}
if (GET_SIGN(bip.op1) == BIG_POSITIVE) {
if (GET_SIGN(bip.op2) == BIG_POSITIVE) {
/* op1 >= 0 and op2 >= 0 */
if (bigUcmp() >= 0) {
/* |op1| >= |op2| */
bigUsub();
SET_SIGN(bip.res, BIG_POSITIVE);
} else {
/* |op1| < |op2| */
bigXchg();
bigUsub();
SET_SIGN(bip.res, BIG_NEGATIVE);
bigXchg();
}
} else {
/* op1 >= 0 and op2 < 0 */
bigUadd();
SET_SIGN(bip.res, BIG_POSITIVE);
}
} else {
if (GET_SIGN(bip.op2) == BIG_POSITIVE) {
/* op1 < 0 and op2 >= 0 */
bigUadd();
SET_SIGN(bip.res, BIG_NEGATIVE);
} else {
/* op1 < 0 and op2 < 0 */
if (bigUcmp() <= 0) {
/* |op1| <= |op2| */
bigXchg();
bigUsub();
SET_SIGN(bip.res, BIG_POSITIVE);
bigXchg();
} else {
/* |op1| > |op2| */
bigUsub();
SET_SIGN(bip.res, BIG_NEGATIVE);
}
}
}
}
/*
* big integer multiplication
*
* operands in bip.op1 and bip.op2
* result in bip.res
*/
void bigMul(void) {
if (bip.op1 == NULL ||
bip.op2 == NULL) {
nilRefException();
}
bigUmul();
if (GET_SIGN(bip.op1) == GET_SIGN(bip.op2) || GET_ND(bip.res) == 0) {
SET_SIGN(bip.res, BIG_POSITIVE);
} else {
SET_SIGN(bip.res, BIG_NEGATIVE);
}
}
/*
* big integer division, truncating towards zero
*
* dividend in bip.op1, divisor in bip.op2
* quotient in bip.res, remainder in bip.rem
*/
void bigDiv(void) {
if (bip.op1 == NULL ||
bip.op2 == NULL) {
nilRefException();
}
bigUdiv();
if (GET_SIGN(bip.op1) == GET_SIGN(bip.op2) || GET_ND(bip.res) == 0) {
SET_SIGN(bip.res, BIG_POSITIVE);
} else {
SET_SIGN(bip.res, BIG_NEGATIVE);
}
if (GET_SIGN(bip.op1) == BIG_POSITIVE || GET_ND(bip.rem) == 0) {
SET_SIGN(bip.rem, BIG_POSITIVE);
} else {
SET_SIGN(bip.rem, BIG_NEGATIVE);
}
}
/**************************************************************/
/* big integer conversions */
/*
* conversion int --> big
*
* operand in parameter
* result in bip.res
*/
void bigFromInt(int n) {
int i;
bip.res = newBig(sizeof(int));
if (n < 0) {
n = -n;
SET_SIGN(bip.res, BIG_NEGATIVE);
} else {
SET_SIGN(bip.res, BIG_POSITIVE);
}
for (i = 0; i < sizeof(int); i++) {
SET_DIGIT(bip.res, i, n & 0xFF);
n >>= 8;
}
while (--i >= 0 && GET_DIGIT(bip.res, i) == 0) ;
SET_ND(bip.res, i + 1);
}
/*
* conversion big --> int
*
* operand in bip.op1
* result is returned
*/
int bigToInt(void) {
int nd;
int i;
int res;
if (bip.op1 == NULL) {
nilRefException();
}
nd = GET_ND(bip.op1);
if (nd > 4 ||
(nd == 4 && GET_DIGIT(bip.op1, 3) >= 0x80)) {
fatalError("big integer too big for conversion to int");
}
res = 0;
for (i = nd - 1; i >= 0; i--) {
res <<= 8;
res |= (unsigned int) GET_DIGIT(bip.op1, i);
}
if (GET_SIGN(bip.op1) == BIG_NEGATIVE) {
res = -res;
}
return res;
}
/**************************************************************/
/* big integer I/O */
/*
* read a big integer
*
* stream to read from in parameter
* result in bip.res
*/
void bigRead(FILE *in) {
int c;
int positive;
c = fgetc(in);
while (isspace(c)) {
c = fgetc(in);
}
if (c == '-') {
positive = 0;
c = fgetc(in);
} else {
positive = 1;
if (c == '+') {
c = fgetc(in);
}
}
if (!isdigit(c)) {
fatalError("no digits in input");
}
bigFromInt(10);
bip.rem = bip.res;
bigFromInt(0);
while (isdigit(c)) {
bip.op1 = bip.res;
bip.op2 = bip.rem;
bigUmul();
bip.op1 = bip.res;
bigFromInt(c - '0');
bip.op2 = bip.res;
bigUadd();
c = fgetc(in);
}
ungetc(c, in);
if (positive || GET_ND(bip.res) == 0) {
SET_SIGN(bip.res, BIG_POSITIVE);
} else {
SET_SIGN(bip.res, BIG_NEGATIVE);
}
}
/*
* print a big integer
*
* stream to write to in parameter
* number to print in bip.op1
*/
void bigPrint(FILE *out) {
int nd;
unsigned char r;
int skipZero;
if (bip.op1 == NULL) {
nilRefException();
}
nd = GET_ND(bip.op1);
if (nd == 0) {
fprintf(out, "0");
return;
}
if (GET_SIGN(bip.op1) == BIG_NEGATIVE) {
fprintf(out, "-");
}
/* number of digits in base 10 = number of digits
in base 256 * log10(256), and log10(256) < 2.5 */
nd = 2 * nd + nd / 2;
bip.rem = bip.op1;
bigFromInt(10);
bip.op2 = bip.res;
bigFromInt(1);
while (nd != 0) {
bip.op1 = bip.res;
bigUmul();
nd--;
}
bip.op1 = bip.rem;
bip.op2 = bip.res;
skipZero = 1;
do {
bigUdiv();
if (GET_ND(bip.res) == 0) {
if (!skipZero) {
fprintf(out, "0");
}
} else {
if (GET_ND(bip.res) != 1) {
fatalError("internal library error #7 - THIS SHOULD NEVER HAPPEN!");
}
fprintf(out, "%c", GET_DIGIT(bip.res, 0) + '0');
skipZero = 0;
}
bip.op1 = bip.rem;
bip.rem = bip.op2;
r = bigUdiv1(10);
bip.op2 = bip.rem;
} while (r == 0);
}
/**************************************************************/
/* debugging */
/*
* dump a big integer object
*/
void bigDump(FILE *out, BigObjRef bigObjRef) {
int nd;
unsigned char sign;
int i;
if (bigObjRef == NULL) {
nilRefException();
}
nd = GET_ND(bigObjRef);
sign = GET_SIGN(bigObjRef);
fprintf(out, "[%d %c", nd, sign == BIG_POSITIVE ? '+' : '-');
for (i = 0; i < nd; i++) {
fprintf(out, " %02X", GET_DIGIT(bigObjRef, i));
}
fprintf(out, "]");
}

60
bigint/src/bigint.h Normal file
View File

@@ -0,0 +1,60 @@
/*
* bigint.h -- big integer library
*/
#ifndef _BIGINT_H_
#define _BIGINT_H_
/* object representation */
typedef void* BigObjRef;
#include <stdio.h>
typedef struct {
int nd; /* number of digits; array may be bigger */
/* nd = 0 exactly when number = 0 */
unsigned char sign; /* one of BIG_NEGATIVE or BIG_POSITIVE */
/* zero always has BIG_POSITIVE here */
unsigned char digits[1]; /* the digits proper; number base is 256 */
/* LS digit first; MS digit is not zero */
} Big;
#include "support.h"
/* big integer processor registers */
typedef struct {
BigObjRef op1; /* first (or single) operand */
BigObjRef op2; /* second operand (if present) */
BigObjRef res; /* result of operation */
BigObjRef rem; /* remainder in case of division */
} BIP;
extern BIP bip; /* registers of the processor */
/* big integer processor functions */
int bigSgn(void); /* sign */
int bigCmp(void); /* comparison */
void bigNeg(void); /* negation */
void bigAdd(void); /* addition */
void bigSub(void); /* subtraction */
void bigMul(void); /* multiplication */
void bigDiv(void); /* division */
void bigFromInt(int n); /* conversion int --> big */
int bigToInt(void); /* conversion big --> int */
void bigRead(FILE *in); /* read a big integer */
void bigPrint(FILE *out); /* print a big integer */
void bigDump(FILE *out, BigObjRef bigObjRef); /* dump a big integer object */
#endif /* _BIGINT_H_ */

BIN
bigint/src/bigint.o Normal file

Binary file not shown.

BIN
bigint/src/libbigint.a Normal file

Binary file not shown.

15
bigint/src/support.h Normal file
View File

@@ -0,0 +1,15 @@
/*
* support.h -- object representation and support functions
*/
#ifndef _SUPPORT_H_
#define _SUPPORT_H_
/* support functions */
void fatalError(char *msg); /* print a message and exit */
void * newPrimObject(int dataSize); /* create a new primitive object */
void * getPrimObjectDataPointer(void * primObject);
#endif /* _SUPPORT_H_ */

28
bigint/tst/Makefile Normal file
View File

@@ -0,0 +1,28 @@
#
# Makefile for big integer test
#
BUILD = ../build
CC = gcc
CFLAGS = -g -Wall -I$(BUILD)/include
LDFLAGS = -g -Wall -L$(BUILD)/lib
LDLIBS = -lbigint
all: testbip
install: all
mkdir -p $(BUILD)/bin
cp testbip $(BUILD)/bin
testbip: testbip.o support.o
$(CC) $(LDFLAGS) -o testbip testbip.o support.o $(LDLIBS)
testbip.o: testbip.c
$(CC) $(CFLAGS) -o testbip.o -c testbip.c
support.o: support.c
$(CC) $(CFLAGS) -o support.o -c support.c
clean:
rm -f *~ testbip.o support.o testbip

55
bigint/tst/support.c Normal file
View File

@@ -0,0 +1,55 @@
/*
* support.c -- support functions for big integer library
*/
#include <stdio.h>
#include <stdlib.h>
#include "support.h"
typedef struct {
unsigned int size; /* byte count of payload data */
unsigned char data[1]; /* payload data, size as needed */
} *ObjRef;
/*
* This routine is called in case a fatal error has occurred.
* It should print the error message and terminate the program.
*/
void fatalError(char *msg) {
printf("Fatal error: %s\n", msg);
exit(1);
}
/*
* This function is called whenever a new primitive object with
* a certain amount of internal memory is needed. It should return
* an object reference to a regular object, which contains a freely
* usable memory area of at least the requested size (measured in
* bytes). The memory area need not be initialized in any way.
*
* Note that this function may move all objects in memory at will
* (due to, e.g., garbage collection), as long as the pointers in
* the global "bip" structure point to the correct objects when
* the function returns.
*/
void * newPrimObject(int dataSize) {
ObjRef bigObjRef;
bigObjRef = malloc(sizeof(unsigned int) +
dataSize * sizeof(unsigned char));
if (bigObjRef == NULL) {
fatalError("newPrimObject() got no memory");
}
bigObjRef->size = dataSize;
return bigObjRef;
}
void * getPrimObjectDataPointer(void * obj){
ObjRef oo = ((ObjRef) (obj));
return oo->data;
}

BIN
bigint/tst/support.o Normal file

Binary file not shown.

BIN
bigint/tst/testbip Executable file

Binary file not shown.

1253
bigint/tst/testbip.c Normal file

File diff suppressed because it is too large Load Diff

BIN
bigint/tst/testbip.o Normal file

Binary file not shown.

View File

@@ -6,13 +6,13 @@
#include <stdlib.h> #include <stdlib.h>
#include "program.c" #include "program.c"
unsigned int fromFile(char *path, struct program *program) { unsigned int fromFile(char *path, struct program program) {
unsigned int countInstructions; unsigned int countInstructions;
unsigned int staticVars; unsigned int staticVars;
FILE *fptr; FILE *fptr;
fptr = fopen(path, "r"); fptr = fopen(path, "r");
if (fptr == NULL) { if (fptr == NULL) {
printf("Error: cannot open code file %s\n", path); printf("Error: cannot open code file %s", path);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
unsigned int buffer[4]; unsigned int buffer[4];

3
compile_flags.txt Normal file
View File

@@ -0,0 +1,3 @@
-Ibigint/build/include
-Lbigint/build/lib
-lbigint

View File

@@ -1,5 +1,7 @@
#ifndef CONSTS #ifndef CONSTS
#define CONSTS #define CONSTS
#define VERSION 4 #define VERSION 5
#endif #endif /* ifndef CONSTS
#define CONSTS
#define VERSION 2; */

53
debugMenu.c Normal file
View File

@@ -0,0 +1,53 @@
#ifndef DEBUGMENU
#define DEBUGMENU
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "stack.c"
#include "stack.c"
void inspect(struct stack s, int fp){
//todo Does not work dont know why
char input[20];
char ref[20];
char refStr[20];
printf("DEBUG [inspect]: stack, datam object?");
fgets(input,20,stdin);
if (input[0] == 's') printStack(s, fp);
if (input[0] == 'd'){/* todo */ }
if (input[0] == 'o'){
scanf("%19s",ref);
ObjRefContainer container;
container = getRefs(s);
for (int i = 0; i<= container.size; i++) {
sprintf(refStr, "%p", (void *)&container.refs[i]);
if(strcmp(ref, refStr) == 0) printf("Adress exists\n");
else printf("Adress doeas not exist\n");
printf("%s",refStr);
}
}
}
void list(){
//todo
}
void breakpoint(){
//todo
}
void debugMenu(int fp, struct stack stack, int* debug){
char input[20];
while (true) {
printf("DEBUG: inspect, list, breakpoint, run, step, quit?");
fgets(input, 20, stdin);
printf("%s",input);
if(input[0] == 'i') {inspect(stack,fp);}
if(input[0] == 'l') list();
if(input[0] == 'b') breakpoint();
if(input[0] == 's') break;
if(input[0] == 'r') {*debug = 0; break;};
if(input[0] == 'q') exit(0);
strcpy(input, "");
}
}
#endif /* ifndef DEBUGMENU */

View File

@@ -34,5 +34,8 @@
#define CALL 26 #define CALL 26
#define RET 27 #define RET 27
#define DROP 28 #define DROP 28
#define PUSHR 29
#define POPR 30
#define DUP 31
#endif /* ifndef INSREUKTION */ #endif /* ifndef INSREUKTION */

BIN
nja-mac

Binary file not shown.

BIN
nja/nja4

Binary file not shown.

BIN
nja/nja5

Binary file not shown.

BIN
nja/nja6

Binary file not shown.

BIN
nja/nja7

Binary file not shown.

BIN
nja/nja8

Binary file not shown.

BIN
njvm-3

Binary file not shown.

393
njvm.c
View File

@@ -1,303 +1,256 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <string.h> #include <string.h>
#include "consts.c"
#include "instruktion.c" #include "instruktion.c"
#include "code.c" #include "code.c"
#include "stack.c" #include "stack.c"
#include "program.c" #include "program.c"
#include "codeReader.c" #include "codeReader.c"
#include "SDA.c" #include "SDA.c"
#include "debugMenu.c"
// Program #include "bigint.h"
struct program *program; // Debug
// SDA
int fp;
int debug = 0; int debug = 0;
// Stack
struct stack stack;
#define SIZE 1000
//Register
struct stack reg;
// Program
struct program program;
// SDA
struct sda sda;
unsigned fp;
void version(void) { void version(void) {
printf("Ninja Virtual Machine version %i (compiled %s, %s)\n", VERSION, __DATE__, __TIME__); printf("Ninja Virtual Machine version %i (compiled %s, %s)\n", 0, __DATE__, __TIME__);
bigFromInt(9);
bip.op1 = bip.res;
bigFromInt(10);
bip.op2 = bip.res;
bigAdd();
bip.op1 = bip.res;
bigPrint(stdout);
} }
void help(void) { void help(void) {
printf("Usage: ./njvm [options] <code file>\n\t--debug\tstart virtual machine in debug mode\n\t--version\tshow version and exit\n\t--help\t\tshow this help and exit\n"); printf("Usage: ./njvm [options] <code file>\n\t--debug\tstart virtual machine in debug mode\n\t--version\tshow version and exit\n\t--help\t\tshow this help and exit\n");
} }
void execute(struct program *program, struct sda *sda) { void execute(struct program program) {
struct stack stack; int i;
stack.size = 1000;
stack.currentFrame = 0;
struct stack callStack;
callStack.size = 1000;
callStack.currentFrame = 0;
for (int i = 0; i < stack.size; ++i) {
struct stackFrame *frame = malloc(sizeof(struct stackFrame));
frame->fp = malloc(sizeof(int) * stack.size);
frame->sp = malloc(sizeof(int) * stack.size);
frame->bp = NULL;
stack.frames[i] = frame;
}
for (int i = 0; i < callStack.size; ++i) {
struct stackFrame *frame = malloc(sizeof(struct stackFrame));
frame->fp = malloc(sizeof(int) * stack.size);
frame->sp = malloc(sizeof(int) * stack.size);
frame->bp = NULL;
callStack.frames[i] = frame;
}
struct stackFrame *currentFrame = NULL;
//struct stackFrame *currentCallFrame = NULL;
unsigned int tmp;
int intInput; int intInput;
unsigned int temp;
char charInput; char charInput;
StackSlot tempSlot;
for (int i = 0; i < program->size; ++i) { ObjRef tempObj;
unsigned int instruction = program->program[i]; for (i = 0; i < *program.size; ++i) {
if (i >= program->size) { if (debug == 1) debugMenu(fp,stack,&debug);
printf("Error: Jump out of program memory\n"); switch (program.program[i] >> 24) {
goto end;
}
switch (instruction >> 24) {
case HALT: case HALT:
if (debug == 1) printf("halt\n");
goto end; goto end;
case PUSHC: case PUSHC:
if (debug == 1) printf("PUSHC %d\n", SIGN_EXTEND(IMMEDIATE(instruction))); if (debug == 1) printf("pushc: %i\n", IMMEDIATE(program.program[i]));
push(&stack, SIGN_EXTEND(IMMEDIATE(instruction))); push(stack, stackSlotWithObjRef(getIntObj(SIGN_EXTEND(IMMEDIATE(program.program[i])))));
break; break;
case ADD: case ADD:
if (debug == 1) printf("ADD\n"); if (debug == 1) printf("add: %i + %i\n",peek(stack, 2),peek(stack, 1));
push(&stack, pop(&stack) + pop(&stack)); push(stack, stackSlotWithObjRef(getIntObj(getIntValfromStackSlot(pop(stack)) + getIntValfromStackSlot(pop(stack)))));
break; break;
case SUB: case SUB:
tmp = pop(&stack); if (debug == 1) printf("sub: %i - %i\n", peek(stack, 2), peek(stack, 1));
if (debug == 1) printf("SUB\n"); temp = getIntValfromStackSlot(pop(stack));
if (debug == 1) printf("tmp: %d\n", tmp); push(stack, stackSlotWithObjRef(getIntObj(getIntValfromStackSlot(pop(stack)) - temp)));
push(&stack, pop(&stack) - tmp);
break; break;
case MUL: case MUL:
if (debug == 1) printf("MUL\n"); if (debug == 1) printf("mul: %i * %i\n", peek(stack, 2), peek(stack, 1));
push(&stack, pop(&stack) * pop(&stack)); push(stack, stackSlotWithObjRef(getIntObj(getIntValfromStackSlot(pop(stack)) * getIntValfromStackSlot(pop(stack)))));
break; break;
case DIV: case DIV:
tmp = pop(&stack); if (debug == 1) printf("div: %i / %i\n", peek(stack, 2), peek(stack, 1));
if (debug == 1) printf("DIV\n"); temp = getIntValfromStackSlot(pop(stack));
if (debug == 1) printf("tmp: %d\n", tmp); push(stack, stackSlotWithObjRef(getIntObj(getIntValfromStackSlot(pop(stack)) / temp)));
push(&stack, pop(&stack) / tmp);
break; break;
case MOD: case MOD:
tmp = pop(&stack); if (debug == 1) printf("mod: %i %% %i\n", peek(stack, 2), peek(stack, 1));
if (debug == 1) printf("MOD\n"); temp = getIntValfromStackSlot(pop(stack));
if (debug == 1) printf("tmp: %d\n", tmp); push(stack, stackSlotWithObjRef(getIntObj(getIntValfromStackSlot(pop(stack)))));
push(&stack, pop(&stack) % tmp);
break; break;
case RDINT: case RDINT:
if (debug == 1) printf("rdint\n");
scanf("%i", &intInput); scanf("%i", &intInput);
if (debug == 1) printf("RDINT %d\n", intInput); push(stack, stackSlotWithObjRef(getIntObj(intInput)));
push(&stack, intInput); if (debug == 1) printf("pushed %i\n", intInput);
break; break;
case WRINT: case WRINT:
if (debug == 1) printf("WRINT\n"); if (debug == 1) printf("wrint: %i\n", peek(stack, 1));
printf("%i", pop(&stack)); printf("%i", getIntValfromStackSlot(pop(stack)));
break; break;
case RDCHR: case RDCHR:
if (debug == 1) printf("rdchr\n");
scanf("%c", &charInput); scanf("%c", &charInput);
if (debug == 1) printf("RDCHR %c\n", charInput); push(stack, stackSlotWithObjRef(getIntObj(charInput)));
push(&stack, charInput); if (debug == 1) printf("pushed %c\n", charInput);
break; break;
case WRCHR: case WRCHR:
if (debug == 1) printf("WRCHR\n"); if (debug == 1) printf("wrchr: %c\n", peek(stack, 1));
printf("%c", pop(&stack)); printf("%c", getIntValfromStackSlot(pop(stack)));
break; break;
case PUSHG: case PUSHG:
if (debug == 1) printf("PUSHG %d\n", SIGN_EXTEND(IMMEDIATE(instruction))); if (debug == 1) printf("pushg: %i\n", SIGN_EXTEND(IMMEDIATE(program.program[i])));
currentFrame = stack.frames[stack.currentFrame]; push(stack, stackSlotWithObjRef(getSDA(SIGN_EXTEND(IMMEDIATE(program.program[i])), sda)));
currentFrame->bp = currentFrame->sp;
*currentFrame->sp++ = getSDA(SIGN_EXTEND(IMMEDIATE(instruction)), sda);
break; break;
case POPG: case POPG:
if (debug == 1) printf("POPG %d\n", SIGN_EXTEND(IMMEDIATE(instruction))); if (debug == 1) printf("popg: %i\n", SIGN_EXTEND(IMMEDIATE(program.program[i])));
currentFrame = stack.frames[stack.currentFrame]; setSDA(SIGN_EXTEND(IMMEDIATE(program.program[i])), pop(stack).u.objRef, sda);
currentFrame->bp = currentFrame->sp;
setSDA(SIGN_EXTEND(IMMEDIATE(instruction)), pop(&stack), sda);
break; break;
case ASF: case ASF:
if (debug == 1) printf("ASF %d\n", SIGN_EXTEND(IMMEDIATE(instruction))); if (debug == 1) printf("asf: %i\n", SIGN_EXTEND(IMMEDIATE(program.program[i])));
currentFrame = stack.frames[stack.currentFrame]; push(stack, stackSlotWitchNumber(fp));
push(&stack, *currentFrame->sp); fp = *stack.current;
*currentFrame->sp = stack.currentFrame; *stack.current = *stack.current + SIGN_EXTEND(IMMEDIATE(program.program[i]));
currentFrame->bp = currentFrame->sp;
stack.currentFrame += SIGN_EXTEND(IMMEDIATE(instruction));
break; break;
case RSF: case RSF:
if (debug == 1) printf("RSF\n"); if (debug == 1) printf("rsf: %i\n", SIGN_EXTEND(IMMEDIATE(program.program[i])));
stack.currentFrame = pop(&stack); *stack.current = fp;
currentFrame = stack.frames[stack.currentFrame]; if (debug == 1) printf("pop: %i\n", peek(stack, 1));
currentFrame->bp = NULL; tempSlot = pop(stack) ;
break; fp = tempSlot.u.number;
case PUSHL:
printf("PUSHL %d\n", SIGN_EXTEND(IMMEDIATE(instruction)));
currentFrame = stack.frames[stack.currentFrame];
currentFrame->bp = currentFrame->sp;
int x = SIGN_EXTEND(IMMEDIATE(instruction));
push(&stack, currentFrame->fp[x]);
break; break;
case POPL: case POPL:
if (debug == 1) printf("POPL %d\n", SIGN_EXTEND(IMMEDIATE(instruction))); if (debug == 1) printf("popl: %i\n", SIGN_EXTEND(IMMEDIATE(program.program[i])));
currentFrame = stack.frames[stack.currentFrame]; stack.stack[fp + SIGN_EXTEND(IMMEDIATE(program.program[i]))] = pop(stack);
currentFrame->fp[SIGN_EXTEND(IMMEDIATE(instruction))] = pop(&stack);
break; break;
case EQ: case PUSHL:
if (debug == 1) printf("EQ\n"); if (debug == 1) printf("pushl: %i\n", SIGN_EXTEND(IMMEDIATE(program.program[i])));
if (pop(&stack) == pop(&stack)) { push(stack, stack.stack[fp + SIGN_EXTEND(IMMEDIATE(program.program[i]))]);
push(&stack, 1);
} else {
push(&stack, 0);
}
break; break;
case NE: case NE:
if (debug == 1) printf("NE\n"); if (debug == 1) printf("ne: %i != %i\n", peek(stack, 2), peek(stack, 1));
if (pop(&stack) != pop(&stack)) { if (getIntValfromStackSlot(pop(stack)) != getIntValfromStackSlot(pop(stack))) push(stack, stackSlotWithObjRef(getIntObj(1)));
push(&stack, 1); else push(stack, stackSlotWithObjRef(getIntObj(0)));
} else { break;
push(&stack, 0); case EQ:
} if (debug == 1) printf("eq: %i == %i\n", peek(stack, 2), peek(stack, 1));
if (getIntValfromStackSlot(pop(stack)) == getIntValfromStackSlot(pop(stack))) push(stack, stackSlotWithObjRef(getIntObj(1)));
else push(stack, stackSlotWithObjRef(getIntObj(0)));
break; break;
case LT: case LT:
if (debug == 1) printf("LT\n"); if (debug == 1) printf("lt: %i < %i\n", peek(stack, 2), peek(stack, 1));
tmp = pop(&stack); temp = getIntValfromStackSlot(pop(stack));
if (pop(&stack) < tmp) { if (getIntValfromStackSlot(pop(stack)) < temp) push(stack, stackSlotWithObjRef(getIntObj(1)));
push(&stack, 1); else push(stack, stackSlotWithObjRef(getIntObj(0)));
} else {
push(&stack, 0);
}
break; break;
case LE: case LE:
if (debug == 1) printf("LE\n"); if (debug == 1) printf("le: %i <= %i\n", peek(stack, 2), peek(stack, 1));
tmp = pop(&stack); temp = getIntValfromStackSlot(pop(stack));
if (pop(&stack) <= tmp) { if (getIntValfromStackSlot(pop(stack)) <= temp) push(stack, stackSlotWithObjRef(getIntObj(1)));
push(&stack, 1); else push(stack, stackSlotWithObjRef(getIntObj(0)));
} else {
push(&stack, 0);
}
break; break;
case GT: case GT:
if (debug == 1) printf("GT\n"); if (debug == 1) printf("gt: %i > %i\n", peek(stack, 2), peek(stack, 1));
if (debug == 1) printf("peek(1): %d\n", peek(&stack, 1)); temp = getIntValfromStackSlot(pop(stack));
if (debug == 1) printf("peek(2): %d\n", peek(&stack, 2)); if (getIntValfromStackSlot(pop(stack)) > temp) push(stack, stackSlotWithObjRef(getIntObj(1)));
if (debug == 1) printf("peek(1) > peek(2): %d\n", peek(&stack, 2) > peek(&stack, 1)); else push(stack, stackSlotWithObjRef(getIntObj(0)));
tmp = pop(&stack);
if (pop(&stack) > tmp) {
push(&stack, 1);
} else {
push(&stack, 0);
}
break; break;
case GE: case GE:
if (debug == 1) printf("GE\n"); if (debug == 1) printf("ge: %i >= %i\n", peek(stack, 2), peek(stack, 1));
tmp = pop(&stack); temp = getIntValfromStackSlot(pop(stack));
if (pop(&stack) >= tmp) { if (getIntValfromStackSlot(pop(stack)) >= temp) push(stack, stackSlotWithObjRef(getIntObj(1)));
push(&stack, 1); else push(stack, stackSlotWithObjRef(getIntObj(0)));
} else {
push(&stack, 0);
}
break; break;
case JMP: case BRF:
if (debug == 1) printf("JMP %d\n", SIGN_EXTEND(IMMEDIATE(instruction))); if (debug == 1) printf("brf: %i\n", SIGN_EXTEND(IMMEDIATE(program.program[i])));
int j = SIGN_EXTEND(IMMEDIATE(program->program[i])); if (debug == 1) printf("pop: %i\n", peek(stack, 1));
if (debug == 1) printf("JMP %d\n", j); if (getIntValfromStackSlot(pop(stack)) == 0) {
if (j-- >= program->size) { i = SIGN_EXTEND(IMMEDIATE(program.program[i])) - 1;
printf("Error: Jump out of program memory\n"); if (debug == 1) printf("new i: %i\n", i);
goto end;
}
i = j;
break;
case BRF: // branch on false
if (debug == 1) printf("BRF %d\nStack: %d\n", SIGN_EXTEND(IMMEDIATE(instruction)), pop(&stack));
if (pop(&stack) == 0) {
int j = SIGN_EXTEND(IMMEDIATE(program->program[i]));
if (j-- >= program->size) {
printf("Error: BRF out of program memory\n");
goto end;
}
i = j;
} }
break; break;
case BRT: case BRT:
if (debug == 1) printf("BRT %d\n", SIGN_EXTEND(IMMEDIATE(instruction))); if (debug == 1) printf("brt: %i\n", SIGN_EXTEND(IMMEDIATE(program.program[i])));
if (pop(&stack) == 1) { if (debug == 1) printf("pop: %i\n", peek(stack, 1));
int j = SIGN_EXTEND(IMMEDIATE(program->program[i])); if (getIntValfromStackSlot(pop(stack)) == 1) {
if (j-- >= program->size) { i = SIGN_EXTEND(IMMEDIATE(program.program[i])) - 1;
printf("Error: BRT out of program memory\n"); if (debug == 1) printf("new i: %i\n", i);
goto end;
}
i = j;
} }
break; break;
case JMP:
if (debug == 1) printf("jmp: %i\n", SIGN_EXTEND(IMMEDIATE(program.program[i])));
i = SIGN_EXTEND(IMMEDIATE(program.program[i])) - 1;
if (debug == 1) printf("new i: %i\n", i);
break;
case CALL: case CALL:
tmp = SIGN_EXTEND(IMMEDIATE(program->program[i])); if (debug == 1) printf("call: %i\n", SIGN_EXTEND(IMMEDIATE(program.program[i])));
if (j-- >= program->size) { push(stack, stackSlotWitchNumber(i));
printf("Error: Call out of program memory\n"); if (debug == 1) printf("push: %i\n", i + 1);
goto end; i = SIGN_EXTEND(IMMEDIATE(program.program[i])) - 1;
} if (debug == 1) printf("new i: %i\n", i);
push(&callStack, i + 1);
i = tmp;
break; break;
case RET: case RET:
if (debug == 1) printf("RET\n"); if (debug == 1) printf("ret\n");
tmp = pop(&callStack); if (debug == 1) printf("pop: %i\n", peek(stack, 1));
if (tmp-- >= program->size) { i = getIntValfromStackSlot(pop(stack));
printf("Error: Return out of program memory\n"); if (debug == 1) printf("new i: %i\n", i);
goto end;
}
i = tmp;
break; break;
case DROP: case DROP:
tmp = SIGN_EXTEND(IMMEDIATE(instruction)); if(debug ==1) printf("drop\n");
if (debug == 1) printf("DROP %d\n", tmp); *stack.current = *stack.current - SIGN_EXTEND(IMMEDIATE(program.program[i]));
for (int b = 0; b < tmp; ++b) { break;
pop(&stack); case DUP:
} if (debug==1) printf("dup\n");
tempObj = pop(stack).u.objRef;
push(stack, stackSlotWithObjRef(tempObj));
push(stack, stackSlotWithObjRef(tempObj));
break;
case POPR:
if (debug==1) printf("popr") ;
push(reg, pop(stack));
break;
case PUSHR:
if(debug == 1) printf("pushr");
push(stack, pop(reg));
break; break;
} }
} }
end: end:
return; return;
} }
// run prog2.bin
void tests(void) { void tests(void) {
printf("Test started\n");
/*struct sda *sda = malloc(sizeof(struct sda));
unsigned int s[1000];
sda->size = 1000;
sda->sda = s;
fromFile("prog2.bin", program);
execute(program, (struct sda *) &sda);*/
printf("Test finished\n");
} }
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
// Initialize the Stack // Initialize the Stack
struct stack stack;
int size = SIZE; int size = SIZE;
stack.size = size; int current = 0;
stack.currentFrame = 0; StackSlot s[SIZE];
stack.size = &size;
stack.current = &current;
stack.stack = s;
// Initialize the registery
int rSize = SIZE;
int rCurrent = 0;
StackSlot r[SIZE];
reg.size = &rSize;
reg.current = &rCurrent;
reg.stack = r;
// Initialize ProgrammSpeicher // Initialize ProgrammSpeicher
int psize = SIZE; int psize = 1000;
int saveProgram = 0;
unsigned int p[1000]; unsigned int p[1000];
program = malloc(sizeof(struct program)); program.size = &psize;
program->size = psize; program.program = p;
program->program = p; program.saveProgram = &saveProgram;
// Initialize runtime variables
int run = 0; int run = 0;
int sizeSDA; int sizeSDA;
@@ -311,6 +264,12 @@ int main(int argc, char *argv[]) {
} else if (strcmp(argv[i], "--help") == 0) { } else if (strcmp(argv[i], "--help") == 0) {
help(); help();
return 0; return 0;
} else if (strcmp(argv[i], "--stack") == 0) {
i++;
// TODO: implement stack size
} else if(strcmp(argv[i], "--heap") == 0) {
i++;
// TODO: implement heap size
} else { } else {
sizeSDA = fromFile(argv[i], program); sizeSDA = fromFile(argv[i], program);
run = 1; run = 1;
@@ -318,28 +277,20 @@ int main(int argc, char *argv[]) {
} }
} }
/*
* Debug mode
*/
if (debug) { if (debug) {
tests(); tests();
} }
/*
* Run program
*/
if (run) { if (run) {
printf("Ninja Virtual Machine started\n"); printf("Ninja Virtual Machine started\n");
struct sda *sda = malloc(sizeof(struct sda)); ObjRef s[sizeSDA];
unsigned int s[sizeSDA]; sda.size = &sizeSDA;
sda->size = sizeSDA; sda.sda = s;
sda->sda = s;
if (debug == 1) printProgram(program); if (debug == 1) printProgram(program);
execute(program, (struct sda *) &sda); execute(program);
printf("Ninja Virtual Machine stopped\n"); printf("Ninja Virtual Machine stopped\n");
} else { } else {
printf("Error: no code file specified\n"); printf("Error: no code file specified\n");
return 1; return 1;
} }
return 0;
} }

BIN
njvm.o Normal file

Binary file not shown.

10
objref.c Normal file
View File

@@ -0,0 +1,10 @@
#ifndef OBJREF
#define OBJREF
typedef struct {
unsigned int size;
unsigned char data[1];
} *ObjRef;
#endif /* ifndef OBJREF
#define OBJREF */

BIN
prog.bin Normal file

Binary file not shown.

View File

@@ -9,21 +9,23 @@
#include <stdio.h> #include <stdio.h>
struct program { struct program {
int *size;
unsigned int *program; unsigned int *program;
int size; int *saveProgram;
}; };
void copyToProgram(const unsigned int codeToCopy[], int size, struct program *program) { void copyToProgram(const unsigned int codeToCopy[], int size, struct program program) {
for (int i = 0; i < size; ++i) { for (int i = 0; i < size; ++i) {
program->program[i] = codeToCopy[i]; program.program[i] = codeToCopy[i];
} }
program->size = size; *program.size = size;
*program.saveProgram = 1;
} }
void printProgram(struct program *program) { void printProgram(struct program program) {
char c[10]; char c[10];
for (int i = 0; i < program->size; i++) { for (int i = 0; i < *program.size; i++) {
switch (program->program[i] >> 24) { switch (program.program[i] >> 24) {
case PUSHC: case PUSHC:
strcpy(c, "pushc"); strcpy(c, "pushc");
break; break;
@@ -76,43 +78,55 @@ void printProgram(struct program *program) {
strcpy(c, "popl"); strcpy(c, "popl");
break; break;
case EQ: case EQ:
strcpy(c,"eq"); strcpy(c, "eq");
break; break;
case NE: case NE:
strcpy(c,"ne"); strcpy(c, "ne");
break; break;
case LT: case LT:
strcpy(c,"lt"); strcpy(c, "lt");
break;
case LE:
strcpy(c, "le");
break; break;
case GT: case GT:
strcpy(c,"gt"); strcpy(c, "gt");
break; break;
case GE: case GE:
strcpy(c,"ge"); strcpy(c, "ge");
break; break;
case JMP: case JMP:
strcpy(c,"jmp"); strcpy(c, "jmp");
break; break;
case BRF: case BRF:
strcpy(c, "brf"); strcpy(c, "brf");
break; break;
case BRT: case BRT:
strcpy(c,"brt"); strcpy(c, "brt");
break; break;
case CALL: case CALL:
strcpy(c,"call"); strcpy(c, "call");
break; break;
case RET: case RET:
strcpy(c,"ret"); strcpy(c, "ret");
break; break;
case DROP: case DROP:
strcpy(c,"drop"); strcpy(c, "drop");
break;
case PUSHR:
strcpy(c, "pushr");
break;
case POPR:
strcpy(c, "popr");
break;
case DUP:
strcpy(c, "dup");
break; break;
default: default:
strcpy(c, "ERROR"); strcpy(c, "ERROR");
break; break;
} }
IMMEDIATE(program->program[i]) ? printf("%03i:\t%s\t%i\n", i, c, SIGN_EXTEND(IMMEDIATE(program->program[i]))) : printf( IMMEDIATE(program.program[i]) ? printf("%03i:\t%s\t%i\n", i, c, SIGN_EXTEND(IMMEDIATE(program.program[i]))) : printf(
"%03i:\t%s\n", i, c); "%03i:\t%s\n", i, c);
} }
} }

BIN
programs/nja Executable file

Binary file not shown.

View File

@@ -1,11 +0,0 @@
pushc 3
pushc 4
add
pushc 10
pushc 6
sub
mul
wrint
pushc 10
wrchr
halt

Binary file not shown.

View File

@@ -1,9 +0,0 @@
pushc -2
rdint
mul
pushc 3
add
wrint
pushc '\n'
wrchr
halt

Binary file not shown.

View File

@@ -1,5 +0,0 @@
rdchr
wrint
pushc '\n'
wrchr
halt

Binary file not shown.

28
programs/prog02.asm Normal file
View File

@@ -0,0 +1,28 @@
//
// prog02.asm -- call/ret with args, but without ret value
//
asf 3
pushc 11
pushc 33
call proc
drop 2
rsf
halt
proc:
asf 2
pushl -4
wrint
pushc '\n'
wrchr
pushc 22
wrint
pushc '\n'
wrchr
pushl -3
wrint
pushc '\n'
wrchr
rsf
ret

32
programs/prog04.asm Normal file
View File

@@ -0,0 +1,32 @@
//
// prog04.asm -- call/ret with args, and with ret value
//
asf 3
pushc 11
wrint
pushc '\n'
wrchr
pushc 11
pushc 33
call proc
drop 2
pushr
wrint
pushc '\n'
wrchr
pushc 33
wrint
pushc '\n'
wrchr
rsf
halt
proc:
asf 2
pushl -3
pushl -4
sub
popr
rsf
ret

View File

@@ -0,0 +1,31 @@
//
// prog1.asm -- an assembler example with global variables
//
// global Integer x;
// global Integer y;
// x = 2;
// y = x + 3;
// x = 7 * y + x;
// writeInteger(x + -33);
// writeCharacter('\n');
pushc 2
popg 0
pushg 0
pushc 3
add
popg 1
pushc 7
pushg 1
mul
pushg 0
add
popg 0
pushg 0
pushc -33
add
wrint
pushc '\n'
wrchr
halt

Binary file not shown.

Binary file not shown.

View File

@@ -1,61 +1,9 @@
// pushc 1
// prog1.asm -- an assembler example with global variables asf 2
// asf 4
pushc 23
// asf 3
// compute the gcd of two positive numbers rsf
// rsf
// global Integer x; rsf
// global Integer y;
// x = readInteger();
// y = readInteger();
// while (x != y) {
// if (x > y) {
// x = x - y;
// } else {
// y = y - x;
// }
// }
// writeInteger(x);
// writeCharacter('\n');
// x = readInteger();
rdint
popg 0
// y = readInteger();
rdint
popg 1
// while ...
L1:
// x != y
pushg 0 // 4
pushg 1
ne
brf L2
// if ...
pushg 0
pushg 1
gt
brf L3
// x = x - y
pushg 0
pushg 1
sub
popg 0
jmp L4
L3:
// y = y - x
pushg 1 // 17
pushg 0
sub
popg 1
L4:
jmp L1 // 21
L2:
// writeInteger(x);
pushg 0 // 22
wrint
// writeCharacter('\n');
pushc '\n'
wrchr
halt halt

Binary file not shown.

View File

@@ -1,12 +1,12 @@
// //
// prog2.asm -- an assembler example with local variables // prog1.asm -- an assembler example with global variables
// //
// //
// compute the gcd of two positive numbers // compute the gcd of two positive numbers
// //
// local Integer x; // global Integer x;
// local Integer y; // global Integer y;
// x = readInteger(); // x = readInteger();
// y = readInteger(); // y = readInteger();
// while (x != y) { // while (x != y) {
@@ -19,45 +19,43 @@
// writeInteger(x); // writeInteger(x);
// writeCharacter('\n'); // writeCharacter('\n');
asf 2
// x = readInteger(); // x = readInteger();
rdint rdint
popl 0 popg 0
// y = readInteger(); // y = readInteger();
rdint rdint
popl 1 popg 1
// while ... // while ...
L1: L1:
// x != y // x != y
pushl 0 pushg 0
pushl 1 pushg 1
ne ne
brf L2 brf L2
// if ... // if ...
pushl 0 pushg 0
pushl 1 pushg 1
gt gt
brf L3 brf L3
// x = x - y // x = x - y
pushl 0 pushg 0
pushl 1 pushg 1
sub sub
popl 0 popg 0
jmp L4 jmp L4
L3: L3:
// y = y - x // y = y - x
pushl 1 pushg 1
pushl 0 pushg 0
sub sub
popl 1 popg 1
L4: L4:
jmp L1 jmp L1
L2: L2:
// writeInteger(x); // writeInteger(x);
pushl 0 pushg 0
wrint wrint
// writeCharacter('\n'); // writeCharacter('\n');
pushc '\n' pushc '\n'
wrchr wrchr
rsf
halt halt

Binary file not shown.

View File

@@ -1,35 +1,63 @@
// //
// prog01.asm -- call/ret without args, and without ret value // prog2.asm -- an assembler example with local variables
// //
asf 3 //
pushc 11 // compute the gcd of two positive numbers
wrint //
pushc '\n' // local Integer x;
wrchr // local Integer y;
call proc // x = readInteger();
pushc 44 // y = readInteger();
// while (x != y) {
// if (x > y) {
// x = x - y;
// } else {
// y = y - x;
// }
// }
// writeInteger(x);
// writeCharacter('\n');
asf 2
// x = readInteger();
rdint
popl 0
// y = readInteger();
rdint
popl 1
// while ...
L1:
// x != y
pushl 0
pushl 1
ne
brf L2
// if ...
pushl 0
pushl 1
gt
brf L3
// x = x - y
pushl 0
pushl 1
sub
popl 0
jmp L4
L3:
// y = y - x
pushl 1
pushl 0
sub
popl 1
L4:
jmp L1
L2:
// writeInteger(x);
pushl 0
wrint wrint
// writeCharacter('\n');
pushc '\n' pushc '\n'
wrchr wrchr
rsf rsf
halt halt
proc:
asf 2
pushc 22
wrint
pushc '\n'
wrchr
call proctwo
rsf
ret
proctwo:
asf 2
pushc 33
wrint
pushc '\n'
wrchr
rsf
ret

Binary file not shown.

View File

@@ -1,28 +1,61 @@
// //
// prog02.asm -- call/ret with args, but without ret value // prog1.asm -- an assembler example with global variables
// //
asf 3 //
pushc 11 // compute the gcd of two positive numbers
pushc 33 //
call proc // global Integer x;
drop 2 // global Integer y;
rsf // x = readInteger();
// y = readInteger();
// while (x != y) {
// if (x > y) {
// x = x - y;
// } else {
// y = y - x;
// }
// }
// writeInteger(x);
// writeCharacter('\n');
// x = readInteger();
rdint
popg 0
// y = readInteger();
rdint
popg 1
// while ...
L1:
// x != y
pushg 0
pushg 1
ne
brf L2
// if ...
pushg 0
pushg 1
gt
brf L3
// x = x - y
pushg 0
pushg 1
sub
popg 0
jmp L4
L3:
// y = y - x
pushg 1
pushg 0
sub
popg 1
L4:
jmp L1
L2:
// writeInteger(x);
pushg 0
wrint
// writeCharacter('\n');
pushc '\n'
wrchr
halt halt
proc:
asf 2
pushl -4
wrint
pushc '\n'
wrchr
pushc 22
wrint
pushc '\n'
wrchr
pushl -3
wrint
pushc '\n'
wrchr
rsf
ret

View File

@@ -1,27 +1,16 @@
// //
// prog02.asm -- call/ret with args, but without ret value // prog04.asm -- call/ret with args, and with ret value
// //
asf 3 pushc 12
pushc 11 rdint
pushc 33 mul
wrint
call proc call proc
drop 2
rsf
halt halt
proc: proc:
asf 2 asf 1
pushl 4
wrint
pushc '\n'
wrchr
pushc 22
wrint
pushc '\n'
wrchr
pushl 3
wrint
pushc '\n' pushc '\n'
wrchr wrchr
rsf rsf

Binary file not shown.

83
stack.c
View File

@@ -3,46 +3,77 @@
// //
#ifndef STACK #ifndef STACK
#define STACK #define STACK
#define SIZE 1000
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include "stackslot.c"
struct stackFrame {
int *fp; // Frame pointer
int *sp; // Stack pointer
int *bp; // Base pointer
};
struct stack { struct stack {
int size; int* size;
int currentFrame; int* current;
struct stackFrame *frames[SIZE]; StackSlot *stack;
}; };
void printStack(struct stack *stack) { typedef struct {
printf("Stack:\n"); unsigned int size;
for (int i = 0; i < stack->size; ++i) { ObjRef *refs;
printf("[%d] = %d\n", i, stack->frames[stack->currentFrame]->sp[i]); }ObjRefContainer;
void printStack(struct stack stack, int fp) {
printf("Stack\nSize:\t\t%i\nCurrent:\t%i\n", *stack.size, *stack.current);
for (int i = *stack.current -1; i >= 0; --i) {
printf("%i\t",i);
if(stack.stack[i].isObjRef){
printf("|%p|", (void *)stack.stack[i].u.objRef);
if(stack.stack[i].u.objRef->size == sizeof(int))
printf("(%i)",*(int *)stack.stack[i].u.objRef->data);
}else {
printf("|%i|", getIntValfromStackSlot(stack.stack[i]));
}
if(fp == i) printf("<-\tFP\n");
else if(*stack.current == i) printf("<-\tSP\n");
else printf("\n");
} }
} }
void push(struct stack *stack, unsigned int value) { ObjRefContainer getRefs(struct stack stack){
struct stackFrame *currentFrame = stack->frames[stack->currentFrame]; ObjRefContainer continer;
*(currentFrame->sp) = value; int counter = 0;
currentFrame->sp++; for (int i = 0; i <= *stack.current; i++) {
if(stack.stack[i].isObjRef == true) counter++;
}
continer.size = counter;
ObjRef *list = (ObjRef *)malloc(counter * sizeof(ObjRef));
for (int i = 0; i<= *stack.current; i++)
if(stack.stack[i].isObjRef == true)
list[counter--] = stack.stack[i].u.objRef;
continer.refs = list;
return continer;
} }
int pop(struct stack *stack) { void push(struct stack s, StackSlot value) {
struct stackFrame *currentFrame = stack->frames[stack->currentFrame]; if (*s.current >= *s.size) {
currentFrame->sp--; printf("Stack Overflow\n");
return *(currentFrame->sp); exit(EXIT_FAILURE);
}
s.stack[*s.current] = value;
*s.current=*s.current + 1;
} }
int peek(struct stack *stack, int steps) { // peek is pop without removing the value StackSlot pop(struct stack s) {
struct stackFrame *currentFrame = stack->frames[stack->currentFrame]; if (*s.current == 0) {
return *(currentFrame->sp - steps); printf("Stack Underflow\n");
exit(EXIT_FAILURE);
}
*s.current = *s.current -1;
return s.stack[*s.current];
} }
int peek(struct stack s, int steps) {
if (*s.current - steps < 0) {
printf("Stack Underflow\n");
exit(EXIT_FAILURE);
}
return getIntValfromStackSlot(s.stack[*s.current - steps]);
}
#endif #endif

57
stackslot.c Normal file
View File

@@ -0,0 +1,57 @@
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#ifndef STACKSLOT
#define STACKSLOT
typedef int Object;
typedef struct {
unsigned int size;
unsigned char data[1];
} *ObjRef;
typedef struct{
bool isObjRef;
union {
ObjRef objRef;
int number;
} u;
} StackSlot;
ObjRef getIntObj(int val){
ObjRef intObject;
unsigned int objSize = sizeof(unsigned int) + sizeof(int);
if ((intObject = malloc(objSize)) == NULL) {
perror("malloc");
}
*(int *)intObject->data=val;
intObject->size=sizeof(int);
return intObject;
}
int getValFromIntObj(ObjRef iref){
return *(int *)iref->data;
}
int getIntValfromStackSlot(StackSlot s){
if(s.isObjRef){
return *(int *)s.u.objRef->data;
}
return s.u.number;
}
void setValIntObj(ObjRef iref, int val){
iref->size=sizeof(int);
*(int *)iref->data=val;
}
StackSlot stackSlotWithObjRef(ObjRef val){
StackSlot *stackSlot;
stackSlot=malloc(sizeof(StackSlot));
stackSlot->isObjRef=true;
stackSlot->u.objRef=val;
return *stackSlot;
}
StackSlot stackSlotWitchNumber(int val){
StackSlot *stackSlot;
stackSlot= malloc(sizeof(StackSlot));
stackSlot->isObjRef=false;
stackSlot->u.number=val;
return *stackSlot;
}
#endif

27
support.c Normal file
View File

@@ -0,0 +1,27 @@
#include "support.h"
#include <stdio.h>
#include <stdlib.h>
#include "objref.c"
void fatalError(char *msg){
printf("Fatal error: %s\n", msg);
exit(1);
}
void * newPrimObject(int dataSize) {
ObjRef bigObjRef;
bigObjRef = malloc(sizeof(unsigned int) +
dataSize * sizeof(unsigned char));
if (bigObjRef == NULL) {
fatalError("newPrimObject() got no memory");
}
bigObjRef->size = dataSize;
return bigObjRef;
}
void * getPrimObjectDataPointer(void * obj){
ObjRef oo = ((ObjRef) (obj));
return oo->data;
}

BIN
support.o Normal file

Binary file not shown.

9
test.c Normal file
View File

@@ -0,0 +1,9 @@
#include <stdio.h>
#include "bigint.h"
int main(int argc, char *argv[])
{
printf("Hallo Welt\n");
bigFromInt(5);
return 0;
}