Compare commits

..

11 Commits

Author SHA1 Message Date
nils polek
509dc5e947 Added the correct version to --version funktion 2024-01-14 15:28:46 +00:00
nils polek
c6ae64250d Added a nja and njc goal to Makefile 2024-01-14 15:24:31 +00:00
nils polek
ffc04172ae Added a Makefile for better use 2024-01-14 13:47:08 +00:00
Nils Polek
f5cab7c013 Testing 2023-12-09 17:48:51 +01:00
de248a5943 update x 2023-12-09 17:19:43 +01:00
4994bd6071 add call and ret function
add drop (idk if it is working right)
add prog5 and prog6
2023-12-07 03:01:24 +01:00
0b042fb912 fix jmp not working
fix arithmetic operations
add prog3 and prog4
add debug to instructions
2023-12-07 00:05:36 +01:00
nils polek
77cae7467e Added Instruktions 2023-12-06 18:03:07 +01:00
6ea2a7e735 move programs to a separate folder
fix pushg, popg, pushl and popl
2023-12-04 02:39:23 +01:00
8a89c6bf70 add prog1 and prog2, asm and bin files 2023-12-04 01:21:36 +01:00
88271c91ca fix prog1.bin not working
add debug parameter
add nja-mac
2023-12-04 01:20:41 +01:00
58 changed files with 462 additions and 3246 deletions

View File

@@ -3,11 +3,8 @@
# Compiler # Compiler
CC = gcc CC = gcc
# program to Run
F = prog.bin
# Compiler flags # Compiler flags
CFLAGS = -I ./bigint/build/include -L ./bigint/build/lib -g -Wall -std=c99 -pedantic CFLAGS = -g -Wall -std=c99 -pedantic
# Source file # Source file
SRC = njvm.c SRC = njvm.c
@@ -22,11 +19,8 @@ all:
clean: clean:
rm -f $(OBJ) $(TARGET) rm -f $(OBJ) $(TARGET)
debug: all
./$(TARGET) --debug $(F)
run: all run: all
./$(TARGET) $(F) ./$(TARGET)
nja: ./nja/nja$(V) nja: ./nja/nja$(V)
./nja/nja$(V) $(IN) $(OUT) ./nja/nja$(V) $(IN) $(OUT)

21
SDA.c
View File

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

View File

@@ -1,22 +0,0 @@
#
# 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)

View File

@@ -1,92 +0,0 @@
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.

Binary file not shown.

View File

@@ -1,60 +0,0 @@
/*
* 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

@@ -1,15 +0,0 @@
/*
* 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.

View File

@@ -1,26 +0,0 @@
#
# 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

View File

@@ -1,987 +0,0 @@
/*
* 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, "]");
}

View File

@@ -1,60 +0,0 @@
/*
* 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_ */

Binary file not shown.

Binary file not shown.

View File

@@ -1,15 +0,0 @@
/*
* 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_ */

View File

@@ -1,28 +0,0 @@
#
# 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

View File

@@ -1,55 +0,0 @@
/*
* 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;
}

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

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", path); printf("Error: cannot open code file %s\n", path);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
unsigned int buffer[4]; unsigned int buffer[4];

View File

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

View File

@@ -1,53 +0,0 @@
#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,8 +34,5 @@
#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 Executable file

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 Executable file

Binary file not shown.

396
njvm.c
View File

@@ -1,249 +1,303 @@
#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"
// Debug
int debug = 0;
// Stack
struct stack stack;
#define SIZE 1000
//Register
struct stack reg;
// Program // Program
struct program program; struct program *program;
// SDA // SDA
struct sda sda; int fp;
unsigned fp; int debug = 0;
void version(void) { void version(void) {
printf("Ninja Virtual Machine version %i (compiled %s, %s)\n", 0, __DATE__, __TIME__); printf("Ninja Virtual Machine version %i (compiled %s, %s)\n", VERSION, __DATE__, __TIME__);
} }
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) { void execute(struct program *program, struct sda *sda) {
int i; struct stack stack;
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;
ObjRef tempObj; for (int i = 0; i < program->size; ++i) {
for (i = 0; i < *program.size; ++i) { unsigned int instruction = program->program[i];
if (debug == 1) debugMenu(fp,stack,&debug); if (i >= program->size) {
switch (program.program[i] >> 24) { printf("Error: Jump out of program memory\n");
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: %i\n", IMMEDIATE(program.program[i])); if (debug == 1) printf("PUSHC %d\n", SIGN_EXTEND(IMMEDIATE(instruction)));
push(stack, stackSlotWithObjRef(getIntObj(SIGN_EXTEND(IMMEDIATE(program.program[i]))))); push(&stack, SIGN_EXTEND(IMMEDIATE(instruction)));
break; break;
case ADD: case ADD:
if (debug == 1) printf("add: %i + %i\n",peek(stack, 2),peek(stack, 1)); if (debug == 1) printf("ADD\n");
push(stack, stackSlotWithObjRef(getIntObj(getIntValfromStackSlot(pop(stack)) + getIntValfromStackSlot(pop(stack))))); push(&stack, pop(&stack) + pop(&stack));
break; break;
case SUB: case SUB:
if (debug == 1) printf("sub: %i - %i\n", peek(stack, 2), peek(stack, 1)); tmp = pop(&stack);
temp = getIntValfromStackSlot(pop(stack)); if (debug == 1) printf("SUB\n");
push(stack, stackSlotWithObjRef(getIntObj(getIntValfromStackSlot(pop(stack)) - temp))); if (debug == 1) printf("tmp: %d\n", tmp);
push(&stack, pop(&stack) - tmp);
break; break;
case MUL: case MUL:
if (debug == 1) printf("mul: %i * %i\n", peek(stack, 2), peek(stack, 1)); if (debug == 1) printf("MUL\n");
push(stack, stackSlotWithObjRef(getIntObj(getIntValfromStackSlot(pop(stack)) * getIntValfromStackSlot(pop(stack))))); push(&stack, pop(&stack) * pop(&stack));
break; break;
case DIV: case DIV:
if (debug == 1) printf("div: %i / %i\n", peek(stack, 2), peek(stack, 1)); tmp = pop(&stack);
temp = getIntValfromStackSlot(pop(stack)); if (debug == 1) printf("DIV\n");
push(stack, stackSlotWithObjRef(getIntObj(getIntValfromStackSlot(pop(stack)) / temp))); if (debug == 1) printf("tmp: %d\n", tmp);
push(&stack, pop(&stack) / tmp);
break; break;
case MOD: case MOD:
if (debug == 1) printf("mod: %i %% %i\n", peek(stack, 2), peek(stack, 1)); tmp = pop(&stack);
temp = getIntValfromStackSlot(pop(stack)); if (debug == 1) printf("MOD\n");
push(stack, stackSlotWithObjRef(getIntObj(getIntValfromStackSlot(pop(stack))))); if (debug == 1) printf("tmp: %d\n", tmp);
push(&stack, pop(&stack) % tmp);
break; break;
case RDINT: case RDINT:
if (debug == 1) printf("rdint\n");
scanf("%i", &intInput); scanf("%i", &intInput);
push(stack, stackSlotWithObjRef(getIntObj(intInput))); if (debug == 1) printf("RDINT %d\n", intInput);
if (debug == 1) printf("pushed %i\n", intInput); push(&stack, intInput);
break; break;
case WRINT: case WRINT:
if (debug == 1) printf("wrint: %i\n", peek(stack, 1)); if (debug == 1) printf("WRINT\n");
printf("%i", getIntValfromStackSlot(pop(stack))); printf("%i", pop(&stack));
break; break;
case RDCHR: case RDCHR:
if (debug == 1) printf("rdchr\n");
scanf("%c", &charInput); scanf("%c", &charInput);
push(stack, stackSlotWithObjRef(getIntObj(charInput))); if (debug == 1) printf("RDCHR %c\n", charInput);
if (debug == 1) printf("pushed %c\n", charInput); push(&stack, charInput);
break; break;
case WRCHR: case WRCHR:
if (debug == 1) printf("wrchr: %c\n", peek(stack, 1)); if (debug == 1) printf("WRCHR\n");
printf("%c", getIntValfromStackSlot(pop(stack))); printf("%c", pop(&stack));
break; break;
case PUSHG: case PUSHG:
if (debug == 1) printf("pushg: %i\n", SIGN_EXTEND(IMMEDIATE(program.program[i]))); if (debug == 1) printf("PUSHG %d\n", SIGN_EXTEND(IMMEDIATE(instruction)));
push(stack, stackSlotWithObjRef(getSDA(SIGN_EXTEND(IMMEDIATE(program.program[i])), sda))); currentFrame = stack.frames[stack.currentFrame];
currentFrame->bp = currentFrame->sp;
*currentFrame->sp++ = getSDA(SIGN_EXTEND(IMMEDIATE(instruction)), sda);
break; break;
case POPG: case POPG:
if (debug == 1) printf("popg: %i\n", SIGN_EXTEND(IMMEDIATE(program.program[i]))); if (debug == 1) printf("POPG %d\n", SIGN_EXTEND(IMMEDIATE(instruction)));
setSDA(SIGN_EXTEND(IMMEDIATE(program.program[i])), pop(stack).u.objRef, sda); currentFrame = stack.frames[stack.currentFrame];
currentFrame->bp = currentFrame->sp;
setSDA(SIGN_EXTEND(IMMEDIATE(instruction)), pop(&stack), sda);
break; break;
case ASF: case ASF:
if (debug == 1) printf("asf: %i\n", SIGN_EXTEND(IMMEDIATE(program.program[i]))); if (debug == 1) printf("ASF %d\n", SIGN_EXTEND(IMMEDIATE(instruction)));
push(stack, stackSlotWitchNumber(fp)); currentFrame = stack.frames[stack.currentFrame];
fp = *stack.current; push(&stack, *currentFrame->sp);
*stack.current = *stack.current + SIGN_EXTEND(IMMEDIATE(program.program[i])); *currentFrame->sp = stack.currentFrame;
currentFrame->bp = currentFrame->sp;
stack.currentFrame += SIGN_EXTEND(IMMEDIATE(instruction));
break; break;
case RSF: case RSF:
if (debug == 1) printf("rsf: %i\n", SIGN_EXTEND(IMMEDIATE(program.program[i]))); if (debug == 1) printf("RSF\n");
*stack.current = fp; stack.currentFrame = pop(&stack);
if (debug == 1) printf("pop: %i\n", peek(stack, 1)); currentFrame = stack.frames[stack.currentFrame];
tempSlot = pop(stack) ; currentFrame->bp = NULL;
fp = tempSlot.u.number;
break;
case POPL:
if (debug == 1) printf("popl: %i\n", SIGN_EXTEND(IMMEDIATE(program.program[i])));
stack.stack[fp + SIGN_EXTEND(IMMEDIATE(program.program[i]))] = pop(stack);
break; break;
case PUSHL: case PUSHL:
if (debug == 1) printf("pushl: %i\n", SIGN_EXTEND(IMMEDIATE(program.program[i]))); printf("PUSHL %d\n", SIGN_EXTEND(IMMEDIATE(instruction)));
push(stack, stack.stack[fp + SIGN_EXTEND(IMMEDIATE(program.program[i]))]); currentFrame = stack.frames[stack.currentFrame];
currentFrame->bp = currentFrame->sp;
int x = SIGN_EXTEND(IMMEDIATE(instruction));
push(&stack, currentFrame->fp[x]);
break; break;
case NE: case POPL:
if (debug == 1) printf("ne: %i != %i\n", peek(stack, 2), peek(stack, 1)); if (debug == 1) printf("POPL %d\n", SIGN_EXTEND(IMMEDIATE(instruction)));
if (getIntValfromStackSlot(pop(stack)) != getIntValfromStackSlot(pop(stack))) push(stack, stackSlotWithObjRef(getIntObj(1))); currentFrame = stack.frames[stack.currentFrame];
else push(stack, stackSlotWithObjRef(getIntObj(0))); currentFrame->fp[SIGN_EXTEND(IMMEDIATE(instruction))] = pop(&stack);
break; break;
case EQ: case EQ:
if (debug == 1) printf("eq: %i == %i\n", peek(stack, 2), peek(stack, 1)); if (debug == 1) printf("EQ\n");
if (getIntValfromStackSlot(pop(stack)) == getIntValfromStackSlot(pop(stack))) push(stack, stackSlotWithObjRef(getIntObj(1))); if (pop(&stack) == pop(&stack)) {
else push(stack, stackSlotWithObjRef(getIntObj(0))); push(&stack, 1);
break; } else {
case LT: push(&stack, 0);
if (debug == 1) printf("lt: %i < %i\n", peek(stack, 2), peek(stack, 1));
temp = getIntValfromStackSlot(pop(stack));
if (getIntValfromStackSlot(pop(stack)) < temp) push(stack, stackSlotWithObjRef(getIntObj(1)));
else push(stack, stackSlotWithObjRef(getIntObj(0)));
break;
case LE:
if (debug == 1) printf("le: %i <= %i\n", peek(stack, 2), peek(stack, 1));
temp = getIntValfromStackSlot(pop(stack));
if (getIntValfromStackSlot(pop(stack)) <= temp) push(stack, stackSlotWithObjRef(getIntObj(1)));
else push(stack, stackSlotWithObjRef(getIntObj(0)));
break;
case GT:
if (debug == 1) printf("gt: %i > %i\n", peek(stack, 2), peek(stack, 1));
temp = getIntValfromStackSlot(pop(stack));
if (getIntValfromStackSlot(pop(stack)) > temp) push(stack, stackSlotWithObjRef(getIntObj(1)));
else push(stack, stackSlotWithObjRef(getIntObj(0)));
break;
case GE:
if (debug == 1) printf("ge: %i >= %i\n", peek(stack, 2), peek(stack, 1));
temp = getIntValfromStackSlot(pop(stack));
if (getIntValfromStackSlot(pop(stack)) >= temp) push(stack, stackSlotWithObjRef(getIntObj(1)));
else push(stack, stackSlotWithObjRef(getIntObj(0)));
break;
case BRF:
if (debug == 1) printf("brf: %i\n", SIGN_EXTEND(IMMEDIATE(program.program[i])));
if (debug == 1) printf("pop: %i\n", peek(stack, 1));
if (getIntValfromStackSlot(pop(stack)) == 0) {
i = SIGN_EXTEND(IMMEDIATE(program.program[i])) - 1;
if (debug == 1) printf("new i: %i\n", i);
} }
break; break;
case BRT: case NE:
if (debug == 1) printf("brt: %i\n", SIGN_EXTEND(IMMEDIATE(program.program[i]))); if (debug == 1) printf("NE\n");
if (debug == 1) printf("pop: %i\n", peek(stack, 1)); if (pop(&stack) != pop(&stack)) {
if (getIntValfromStackSlot(pop(stack)) == 1) { push(&stack, 1);
i = SIGN_EXTEND(IMMEDIATE(program.program[i])) - 1; } else {
if (debug == 1) printf("new i: %i\n", i); push(&stack, 0);
}
break;
case LT:
if (debug == 1) printf("LT\n");
tmp = pop(&stack);
if (pop(&stack) < tmp) {
push(&stack, 1);
} else {
push(&stack, 0);
}
break;
case LE:
if (debug == 1) printf("LE\n");
tmp = pop(&stack);
if (pop(&stack) <= tmp) {
push(&stack, 1);
} else {
push(&stack, 0);
}
break;
case GT:
if (debug == 1) printf("GT\n");
if (debug == 1) printf("peek(1): %d\n", peek(&stack, 1));
if (debug == 1) printf("peek(2): %d\n", peek(&stack, 2));
if (debug == 1) printf("peek(1) > peek(2): %d\n", peek(&stack, 2) > peek(&stack, 1));
tmp = pop(&stack);
if (pop(&stack) > tmp) {
push(&stack, 1);
} else {
push(&stack, 0);
}
break;
case GE:
if (debug == 1) printf("GE\n");
tmp = pop(&stack);
if (pop(&stack) >= tmp) {
push(&stack, 1);
} else {
push(&stack, 0);
} }
break; break;
case JMP: case JMP:
if (debug == 1) printf("jmp: %i\n", SIGN_EXTEND(IMMEDIATE(program.program[i]))); if (debug == 1) printf("JMP %d\n", SIGN_EXTEND(IMMEDIATE(instruction)));
i = SIGN_EXTEND(IMMEDIATE(program.program[i])) - 1; int j = SIGN_EXTEND(IMMEDIATE(program->program[i]));
if (debug == 1) printf("new i: %i\n", i); if (debug == 1) printf("JMP %d\n", j);
if (j-- >= program->size) {
printf("Error: Jump out of program memory\n");
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;
case BRT:
if (debug == 1) printf("BRT %d\n", SIGN_EXTEND(IMMEDIATE(instruction)));
if (pop(&stack) == 1) {
int j = SIGN_EXTEND(IMMEDIATE(program->program[i]));
if (j-- >= program->size) {
printf("Error: BRT out of program memory\n");
goto end;
}
i = j;
}
break; break;
case CALL: case CALL:
if (debug == 1) printf("call: %i\n", SIGN_EXTEND(IMMEDIATE(program.program[i]))); tmp = SIGN_EXTEND(IMMEDIATE(program->program[i]));
push(stack, stackSlotWitchNumber(i)); if (j-- >= program->size) {
if (debug == 1) printf("push: %i\n", i + 1); printf("Error: Call out of program memory\n");
i = SIGN_EXTEND(IMMEDIATE(program.program[i])) - 1; goto end;
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");
if (debug == 1) printf("pop: %i\n", peek(stack, 1)); tmp = pop(&callStack);
i = getIntValfromStackSlot(pop(stack)); if (tmp-- >= program->size) {
if (debug == 1) printf("new i: %i\n", i); printf("Error: Return out of program memory\n");
goto end;
}
i = tmp;
break; break;
case DROP: case DROP:
if(debug ==1) printf("drop\n"); tmp = SIGN_EXTEND(IMMEDIATE(instruction));
*stack.current = *stack.current - SIGN_EXTEND(IMMEDIATE(program.program[i])); if (debug == 1) printf("DROP %d\n", tmp);
break; for (int b = 0; b < tmp; ++b) {
case DUP: pop(&stack);
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;
int current = 0; stack.size = size;
StackSlot s[SIZE]; stack.currentFrame = 0;
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 = 1000; int psize = SIZE;
int saveProgram = 0;
unsigned int p[1000]; unsigned int p[1000];
program.size = &psize; program = malloc(sizeof(struct program));
program.program = p; program->size = psize;
program.saveProgram = &saveProgram; program->program = p;
// Initialize runtime variables
int run = 0; int run = 0;
int sizeSDA; int sizeSDA;
@@ -257,12 +311,6 @@ 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;
@@ -270,20 +318,28 @@ 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");
ObjRef s[sizeSDA]; struct sda *sda = malloc(sizeof(struct sda));
sda.size = &sizeSDA; unsigned int s[sizeSDA];
sda.sda = s; sda->size = sizeSDA;
sda->sda = s;
if (debug == 1) printProgram(program); if (debug == 1) printProgram(program);
execute(program); execute(program, (struct sda *) &sda);
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
prog.bin

Binary file not shown.

View File

@@ -9,23 +9,21 @@
#include <stdio.h> #include <stdio.h>
struct program { struct program {
int *size;
unsigned int *program; unsigned int *program;
int *saveProgram; int size;
}; };
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;
@@ -78,55 +76,43 @@ 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);
} }
} }

Binary file not shown.

11
programs/prog-test-1.asm Normal file
View File

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

BIN
programs/prog-test-1.bin Normal file

Binary file not shown.

9
programs/prog-test-2.asm Normal file
View File

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

BIN
programs/prog-test-2.bin Normal file

Binary file not shown.

5
programs/prog-test-3.asm Normal file
View File

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

BIN
programs/prog-test-3.bin Normal file

Binary file not shown.

View File

@@ -1,28 +0,0 @@
//
// 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

View File

@@ -1,32 +0,0 @@
//
// 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

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

Binary file not shown.

View File

@@ -1,63 +1,35 @@
// //
// prog2.asm -- an assembler example with local variables // prog01.asm -- call/ret without args, and without ret value
// //
// asf 3
// compute the gcd of two positive numbers pushc 11
// wrint
// local Integer x; pushc '\n'
// local Integer y; wrchr
// x = readInteger(); call proc
// y = readInteger(); pushc 44
// 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,61 +1,28 @@
// //
// prog1.asm -- an assembler example with global variables // prog02.asm -- call/ret with args, but without ret value
// //
// asf 3
// compute the gcd of two positive numbers pushc 11
// pushc 33
// global Integer x; call proc
// global Integer y; drop 2
// x = readInteger(); rsf
// y = readInteger(); halt
// while (x != y) {
// if (x > y) {
// x = x - y;
// } else {
// y = y - x;
// }
// }
// writeInteger(x);
// writeCharacter('\n');
// x = readInteger(); proc:
rdint asf 2
popg 0 pushl -4
// 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 wrint
// writeCharacter('\n');
pushc '\n' pushc '\n'
wrchr wrchr
halt pushc 22
wrint
pushc '\n'
wrchr
pushl -3
wrint
pushc '\n'
wrchr
rsf
ret

View File

@@ -1,16 +1,27 @@
// //
// prog04.asm -- call/ret with args, and with ret value // prog02.asm -- call/ret with args, but without ret value
// //
pushc 12 asf 3
rdint pushc 11
mul pushc 33
wrint
call proc call proc
drop 2
rsf
halt halt
proc: proc:
asf 1 asf 2
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,77 +3,46 @@
// //
#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 stack { struct stackFrame {
int* size; int *fp; // Frame pointer
int* current; int *sp; // Stack pointer
StackSlot *stack; int *bp; // Base pointer
}; };
typedef struct { struct stack {
unsigned int size; int size;
ObjRef *refs; int currentFrame;
}ObjRefContainer; struct stackFrame *frames[SIZE];
};
void printStack(struct stack stack, int fp) { void printStack(struct stack *stack) {
printf("Stack\nSize:\t\t%i\nCurrent:\t%i\n", *stack.size, *stack.current); printf("Stack:\n");
for (int i = *stack.current -1; i >= 0; --i) { for (int i = 0; i < stack->size; ++i) {
printf("%i\t",i); printf("[%d] = %d\n", i, stack->frames[stack->currentFrame]->sp[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");
} }
} }
ObjRefContainer getRefs(struct stack stack){ void push(struct stack *stack, unsigned int value) {
ObjRefContainer continer; struct stackFrame *currentFrame = stack->frames[stack->currentFrame];
int counter = 0; *(currentFrame->sp) = value;
for (int i = 0; i <= *stack.current; i++) { currentFrame->sp++;
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;
} }
void push(struct stack s, StackSlot value) { int pop(struct stack *stack) {
if (*s.current >= *s.size) { struct stackFrame *currentFrame = stack->frames[stack->currentFrame];
printf("Stack Overflow\n"); currentFrame->sp--;
exit(EXIT_FAILURE); return *(currentFrame->sp);
}
s.stack[*s.current] = value;
*s.current=*s.current + 1;
} }
StackSlot pop(struct stack s) { int peek(struct stack *stack, int steps) { // peek is pop without removing the value
if (*s.current == 0) { struct stackFrame *currentFrame = stack->frames[stack->currentFrame];
printf("Stack Underflow\n"); return *(currentFrame->sp - steps);
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

View File

@@ -1,57 +0,0 @@
#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