40 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
nils polek
fb8497fbee changed path 2023-12-03 19:39:50 +01:00
dc16504cd7 Aufgabe 2 fertig 2023-12-03 19:30:38 +01:00
2a427a2563 Aufgabe 2 fertig 2023-12-03 18:19:39 +01:00
0e52973475 Aufgabe 2 fertig 2023-12-03 18:14:27 +01:00
nils polek
8b3770df80 added codeReader and consts.c 2023-12-03 16:10:33 +01:00
dc33e46e24 update help 2023-12-03 14:59:02 +01:00
c900a0444f fix printing negative numbers 2023-12-03 14:29:07 +01:00
c16fe6349b add error message if no program selected
fix error with negative numbers
2023-12-03 14:24:22 +01:00
1363db7c11 Finished cleaning up the code 2023-10-30 12:51:42 +01:00
dfedf2e717 test 2023-10-30 11:59:56 +01:00
4d547cca6a #include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "instruktion.c"
#include "code.c"
#include "stack.c"

//Comment to disable debug

// #define DEBUG

// Stack
struct stack stack;
#define SIZE 1000

unsigned int* programmSpeicher;

void copyToProgramm(unsigned int codeToCopy[]){
  programmSpeicher = codeToCopy;
}

void version(void) {
    printf("Ninja Virtual Machine version %i (compiled %s, %s)\n", 0, __DATE__, __TIME__);
}

void help(void) {
    printf("usage: ./njvm [option] [option] ...\n\t--version\tshow version and exit\n\t--help\t\tshow this help and exit\n");
}
void printProgramm(){
  int i = 0;
  char c[10];
  while (programmSpeicher[i] != 0)
  {
    switch (programmSpeicher[i] >> 24) {
      case PUSHC:
        strcpy(c,"pushc");
      break;
      case ADD:
        strcpy(c,"add");
      break;
      case SUB:
        strcpy(c,"sub");
      break;
      case MUL:
        strcpy(c,"mul");
      break;
      case DIV:
        strcpy(c,"div");
      break;
      case MOD:
        strcpy(c,"mod");
      break;
      case RDINT:
        strcpy(c,"rdint");
      break;
      case WRINT:
        strcpy(c,"wrint");
      break;
      case RDCHR:
        strcpy(c,"rdchr");
      break;
      case WRCHR:
        strcpy(c,"wrchr");
      break;
      default:
        strcpy(c,"halt");
      break;
    }
    IMMEDIATE(programmSpeicher[i])? printf("%03i:\t%s\t%i\n",i,c,IMMEDIATE(programmSpeicher[i])) : printf("%03i:\t%s\n",i,c);
       i++;
  }
  printf("%03i:\thalt\n",i);
}
void execute(void) {
    int i = 0;
    int intInput;
    int temp;
    char charInput;
    while (1) {

        switch (programmSpeicher[i] >> 24) {
            case HALT:
                  goto end;
                break;
            case PUSHC:
                  push(stack,IMMEDIATE(programmSpeicher[i]));
                break;
            case ADD:
                  push(stack,pop(stack)+pop(stack));
                break;
            case SUB:
                  temp = pop(stack);
                  push(stack,pop(stack) - temp);
                break;
            case MUL:
                  push(stack,pop(stack)*pop(stack));
                break;
            case DIV:
                  temp = pop(stack);
                  push(stack,pop(stack)/temp);
                break;
            case MOD:
                  temp = pop(stack);
                  push(stack,pop(stack)%temp);
                break;
            case RDINT:
                  scanf("%i",&intInput);
                  push(stack,intInput);
                break;
            case WRINT:
                  printf("%i",pop(stack));
                break;
            case RDCHR:
                  scanf("%c",&charInput);
                  push(stack,charInput);
                break;
            case WRCHR:
                  printf("%c",pop(stack));
                break;
        }
        i++;
    }
end:
  return;
}
#ifdef DEBUG

void tests(void){
  printf("Runnig debug mode\n");
  copyToProgramm(code1);
  printProgramm();
  execute();
}

#endif /* ifdef DEBUG */

int main(int argc, char *argv[]) {
  int size = SIZE;
  int current = 0;
  unsigned int s[SIZE];
  stack.size = &size;
  stack.current = &current;
  stack.stack = s;
    #ifdef DEBUG
      tests();
    #endif /* ifdef DEBUG */
     if (argc > 1) {
        if (strcmp(argv[1], "--version") == 0) {
            version();
        } else if (strcmp(argv[1], "--help") == 0) {
            help();
        } else if (strcmp(argv[1], "--prog1") == 0) {
            copyToProgramm(code1);
            goto run;
        } else if (strcmp(argv[1],"--prog2") == 0) {
            copyToProgramm(code2);
            goto run;
        }else if (strcmp(argv[1],"--prog3") == 0) {
            copyToProgramm(code3);
            goto run;
        }else {
            printf("unknown command line argument '%s', try './njvm --help'", argv[1]);
        }
    } else {
  run:
//    Started
        printf("Ninja Virtual Machine started\n");
        printProgramm();
        execute();
//    Stopped
        printf("Ninja Virtual Machine stopped\n");
        return 0;
    }
}
2023-10-30 00:24:55 +01:00
6740f41edc stack organized 2023-10-30 00:17:17 +01:00
9890324ea5 Structurized the code 2023-10-26 22:36:54 +02:00
efe7663637 Print program 2023-10-26 17:26:59 +02:00
4e629a6ca7 orginized projekt 2023-10-26 14:49:57 +02:00
d947afdf03 Test 2023-10-26 14:03:31 +02:00
d05c415295 Now HALT works correctly 2023-10-22 13:51:32 +02:00
d23727f6da Added the 3 progamms 2023-10-21 21:31:04 +02:00
62ede37645 Operations now work 2023-10-21 21:09:01 +02:00
9f7b69e5f7 Added the option to test and basic math to execute() 2023-10-21 19:14:48 +02:00
nplk84
7d7b67f7f2 Stack overflow errors get detected correctly 2023-10-16 11:56:38 +02:00
nplk84
655da552de Added Keys 2023-10-15 19:08:12 +02:00
4f23944408 fix some warnings 2023-10-15 19:05:43 +02:00
19de6c2dbc remove config.h.in 2023-10-15 19:01:28 +02:00
49b064d74d remove config file
update CMakeLists.txt
update gitignore file
2023-10-15 19:00:46 +02:00
nplk84
119b5be760 deleated some shit 2023-10-15 18:50:37 +02:00
nplk84
23690576ea Added Keys 2023-10-15 18:23:32 +02:00
nplk84
8a7d900d9a Added the Stack 2023-10-12 14:42:31 +02:00
nplk84
1b742e0007 Added the Stack 2023-10-12 12:57:51 +02:00
50 changed files with 1124 additions and 60 deletions

6
.gitignore vendored Normal file
View File

@@ -0,0 +1,6 @@
.idea
cmake-build-debug
njvm
njvm.dSYM
njvm.exe
njvm2

8
.idea/.gitignore generated vendored
View File

@@ -1,8 +0,0 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

8
.idea/modules.xml generated
View File

@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/ninja.iml" filepath="$PROJECT_DIR$/.idea/ninja.iml" />
</modules>
</component>
</project>

2
.idea/ninja.iml generated
View File

@@ -1,2 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module classpath="CMake" type="CPP_MODULE" version="4" />

6
.idea/vcs.xml generated
View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

View File

@@ -2,11 +2,8 @@ cmake_minimum_required(VERSION 3.0)
project(ninja LANGUAGES C)
set(CMAKE_C_STANDARD 99)
set(PROJECT_VERSION 0)
configure_file(
${CMAKE_SOURCE_DIR}/config.h.in
${CMAKE_BINARY_DIR}/config.h
)
include_directories(${CMAKE_BINARY_DIR})
add_executable(ninja
njvm.c config.h.in)
add_compile_options(-g -Wall -pedantic)
add_executable(ninja njvm.c
SDA.c)

29
Makefile Normal file
View File

@@ -0,0 +1,29 @@
# Makefile for a simple C program
# Compiler
CC = gcc
# Compiler flags
CFLAGS = -g -Wall -std=c99 -pedantic
# Source file
SRC = njvm.c
# Executable name
TARGET = njvm
# Default target
all:
$(CC) $(CFLAGS) -o $(TARGET) $(SRC)
# Clean up
clean:
rm -f $(OBJ) $(TARGET)
run: all
./$(TARGET)
nja: ./nja/nja$(V)
./nja/nja$(V) $(IN) $(OUT)
njc: ./njc/njc$(V)
./njc/njc$(V) $(IN) $(OUT)

28
SDA.c Normal file
View File

@@ -0,0 +1,28 @@
//
// Created by Nils on 03.12.2023
//
#ifndef SDA
#define SDA
#include <stdio.h>
struct sda {
unsigned int *sda;
int size;
};
int getSDA(unsigned int offset, struct sda *sda) {
return sda->sda[offset];
}
void setSDA(unsigned int offset, int value, struct sda *sda) {
sda->sda[offset] = value;
}
void printSDA(struct sda *sda) {
printf("SDA:\n");
for (int i = 0; i < sda->size; ++i) {
printf("[%d] = %d\n", i, sda->sda[i]);
}
}
#endif

38
code.c Normal file
View File

@@ -0,0 +1,38 @@
#ifndef CODE
#define CODE
#include "instruktion.c"
unsigned int code1[] = {
(PUSHC << 24) | IMMEDIATE(3),
(PUSHC << 24) | IMMEDIATE(4),
(ADD << 24),
(PUSHC << 24) | IMMEDIATE(10),
(PUSHC << 24) | IMMEDIATE(6),
(SUB << 24),
(MUL << 24),
(WRINT << 24),
(PUSHC << 24) | IMMEDIATE(10),
(WRCHR << 24),
(HALT)
};
unsigned int code2[] = {
(PUSHC << 24) | IMMEDIATE(SIGN_EXTEND(-2)),
(RDINT << 24),
(MUL << 24),
(PUSHC << 24) | IMMEDIATE(3),
(ADD << 24),
(WRINT << 24),
(PUSHC << 24) | IMMEDIATE('\n'),
(WRCHR << 24),
(HALT << 24)
};
unsigned int code3[] = {
(RDCHR << 24),
(WRINT << 24),
(PUSHC << 24) | IMMEDIATE('\n'),
(WRCHR << 24),
(HALT << 24)
};
#endif

37
codeReader.c Normal file
View File

@@ -0,0 +1,37 @@
#ifndef CODEREADER
#define CODEREADER
#include "consts.c"
#include <stdio.h>
#include <stdlib.h>
#include "program.c"
unsigned int fromFile(char *path, struct program *program) {
unsigned int countInstructions;
unsigned int staticVars;
FILE *fptr;
fptr = fopen(path, "r");
if (fptr == NULL) {
printf("Error: cannot open code file %s\n", path);
exit(EXIT_FAILURE);
}
unsigned int buffer[4];
fread(buffer, 4, 4, fptr);
// Check file type
if (buffer[0] != 0x46424A4E) {
printf("Error: wrong file type");
exit(EXIT_FAILURE);
}
if (buffer[1] != VERSION) {
printf("Error: wrong version");
exit(EXIT_FAILURE);
}
countInstructions = buffer[2];
staticVars = buffer[3];
unsigned int instBuffer[countInstructions];
fread(instBuffer, 4, countInstructions, fptr);
copyToProgram(instBuffer, countInstructions, program);
return staticVars;
}
#endif /* ifdef CODEREADER */

View File

@@ -1 +0,0 @@
#define PROJECT_VERSION @PROJECT_VERSION@

5
consts.c Normal file
View File

@@ -0,0 +1,5 @@
#ifndef CONSTS
#define CONSTS
#define VERSION 4
#endif

38
instruktion.c Normal file
View File

@@ -0,0 +1,38 @@
#ifndef INSREUKTION
#define INSREUKTION
#define IMMEDIATE(x) ((x) & 0x00FFFFFF)
#define SIGN_EXTEND(i) ((i) & 0x00800000 ? (i) | 0xFF000000 : (i))
#define HALT 0
#define PUSHC 1
#define ADD 2
#define SUB 3
#define MUL 4
#define DIV 5
#define MOD 6
#define RDINT 7
#define WRINT 8
#define RDCHR 9
#define WRCHR 10
#define PUSHG 11
#define POPG 12
#define ASF 13
#define RSF 14
#define PUSHL 15
#define POPL 16
#define EQ 17
#define NE 18
#define LT 19
#define LE 20
#define GT 21
#define GE 22
#define JMP 23
#define BRF 24
#define BRT 25
#define CALL 26
#define RET 27
#define DROP 28
#endif /* ifndef INSREUKTION */

BIN
nja-mac Executable file

Binary file not shown.

BIN
nja/nja2 Executable file

Binary file not shown.

BIN
nja/nja3 Executable file

Binary file not shown.

13
nja/nja4 Executable file
View File

@@ -0,0 +1,13 @@
--2024-01-14 15:04:22-- https://git.thm.de/arin07/KSP_public/-/raw/master/aufgaben/a4/nja?inline=false
Loaded CA certificate '/etc/ssl/certs/ca-certificates.crt'
Resolving git.thm.de (git.thm.de)... 212.201.6.138
Connecting to git.thm.de (git.thm.de)|212.201.6.138|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 56947 (56K) [application/octet-stream]
Saving to: nja?inline=false
0K .......... .......... .......... .......... .......... 89% 1.02M 0s
50K ..... 100% 18.3M=0.05s
2024-01-14 15:04:22 (1.13 MB/s) - nja?inline=false saved [56947/56947]

13
nja/nja5 Executable file
View File

@@ -0,0 +1,13 @@
--2024-01-14 15:04:59-- https://git.thm.de/arin07/KSP_public/-/raw/master/aufgaben/a5/nja?inline=false
Loaded CA certificate '/etc/ssl/certs/ca-certificates.crt'
Resolving git.thm.de (git.thm.de)... 212.201.6.138
Connecting to git.thm.de (git.thm.de)|212.201.6.138|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 56947 (56K) [application/octet-stream]
Saving to: nja?inline=false
0K .......... .......... .......... .......... .......... 89% 1.07M 0s
50K ..... 100% 18.4M=0.05s
2024-01-14 15:05:00 (1.18 MB/s) - nja?inline=false saved [56947/56947]

13
nja/nja6 Executable file
View File

@@ -0,0 +1,13 @@
--2024-01-14 15:05:08-- https://git.thm.de/arin07/KSP_public/-/raw/master/aufgaben/a6/nja?inline=false
Loaded CA certificate '/etc/ssl/certs/ca-certificates.crt'
Resolving git.thm.de (git.thm.de)... 212.201.6.138
Connecting to git.thm.de (git.thm.de)|212.201.6.138|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 56947 (56K) [application/octet-stream]
Saving to: nja?inline=false.1
0K .......... .......... .......... .......... .......... 89% 1.04M 0s
50K ..... 100% 25.8M=0.05s
2024-01-14 15:05:08 (1.15 MB/s) - nja?inline=false.1 saved [56947/56947]

13
nja/nja7 Executable file
View File

@@ -0,0 +1,13 @@
--2024-01-14 15:05:15-- https://git.thm.de/arin07/KSP_public/-/raw/master/aufgaben/a7/nja?inline=false
Loaded CA certificate '/etc/ssl/certs/ca-certificates.crt'
Resolving git.thm.de (git.thm.de)... 212.201.6.138
Connecting to git.thm.de (git.thm.de)|212.201.6.138|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 57195 (56K) [application/octet-stream]
Saving to: nja?inline=false.2
0K .......... .......... .......... .......... .......... 89% 1.23M 0s
50K ..... 100% 11.7M=0.04s
2024-01-14 15:05:16 (1.36 MB/s) - nja?inline=false.2 saved [57195/57195]

13
nja/nja8 Executable file
View File

@@ -0,0 +1,13 @@
--2024-01-14 15:05:26-- https://git.thm.de/arin07/KSP_public/-/raw/master/aufgaben/a8/nja?inline=false
Loaded CA certificate '/etc/ssl/certs/ca-certificates.crt'
Resolving git.thm.de (git.thm.de)... 212.201.6.138
Connecting to git.thm.de (git.thm.de)|212.201.6.138|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 57195 (56K) [application/octet-stream]
Saving to: nja?inline=false.3
0K .......... .......... .......... .......... .......... 89% 1.22M 0s
50K ..... 100% 14.5M=0.04s
2024-01-14 15:05:27 (1.35 MB/s) - nja?inline=false.3 saved [57195/57195]

14
njc/njc4 Executable file
View File

@@ -0,0 +1,14 @@
--2024-01-14 15:07:13-- https://git.thm.de/arin07/KSP_public/-/raw/master/aufgaben/a4/njc?inline=false
Loaded CA certificate '/etc/ssl/certs/ca-certificates.crt'
Resolving git.thm.de (git.thm.de)... 212.201.6.138
Connecting to git.thm.de (git.thm.de)|212.201.6.138|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 137095 (134K) [application/octet-stream]
Saving to: njc?inline=false
0K .......... .......... .......... .......... .......... 37% 1.23M 0s
50K .......... .......... .......... .......... .......... 74% 2.63M 0s
100K .......... .......... .......... ... 100% 9.98M=0.06s
2024-01-14 15:07:14 (2.13 MB/s) - njc?inline=false saved [137095/137095]

14
njc/njc5 Executable file
View File

@@ -0,0 +1,14 @@
--2024-01-14 15:07:20-- https://git.thm.de/arin07/KSP_public/-/raw/master/aufgaben/a5/njc?inline=false
Loaded CA certificate '/etc/ssl/certs/ca-certificates.crt'
Resolving git.thm.de (git.thm.de)... 212.201.6.138
Connecting to git.thm.de (git.thm.de)|212.201.6.138|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 137095 (134K) [application/octet-stream]
Saving to: njc?inline=false.1
0K .......... .......... .......... .......... .......... 37% 1.21M 0s
50K .......... .......... .......... .......... .......... 74% 2.51M 0s
100K .......... .......... .......... ... 100% 11.2M=0.06s
2024-01-14 15:07:21 (2.08 MB/s) - njc?inline=false.1 saved [137095/137095]

14
njc/njc6 Executable file
View File

@@ -0,0 +1,14 @@
--2024-01-14 15:07:28-- https://git.thm.de/arin07/KSP_public/-/raw/master/aufgaben/a6/njc?inline=false
Loaded CA certificate '/etc/ssl/certs/ca-certificates.crt'
Resolving git.thm.de (git.thm.de)... 212.201.6.138
Connecting to git.thm.de (git.thm.de)|212.201.6.138|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 137095 (134K) [application/octet-stream]
Saving to: njc?inline=false.2
0K .......... .......... .......... .......... .......... 37% 1.02M 0s
50K .......... .......... .......... .......... .......... 74% 2.03M 0s
100K .......... .......... .......... ... 100% 11.4M=0.07s
2024-01-14 15:07:28 (1.74 MB/s) - njc?inline=false.2 saved [137095/137095]

15
njc/njc7 Executable file
View File

@@ -0,0 +1,15 @@
--2024-01-14 15:07:49-- https://git.thm.de/arin07/KSP_public/-/raw/master/aufgaben/a7/njc?inline=false
Loaded CA certificate '/etc/ssl/certs/ca-certificates.crt'
Resolving git.thm.de (git.thm.de)... 212.201.6.138
Connecting to git.thm.de (git.thm.de)|212.201.6.138|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 166681 (163K) [application/octet-stream]
Saving to: njc?inline=false.6
0K .......... .......... .......... .......... .......... 30% 1.04M 0s
50K .......... .......... .......... .......... .......... 61% 2.13M 0s
100K .......... .......... .......... .......... .......... 92% 11.2M 0s
150K .......... .. 100% 14.2M=0.08s
2024-01-14 15:07:49 (2.11 MB/s) - njc?inline=false.6 saved [166681/166681]

15
njc/njc8 Executable file
View File

@@ -0,0 +1,15 @@
--2024-01-14 15:07:46-- https://git.thm.de/arin07/KSP_public/-/raw/master/aufgaben/a8/njc?inline=false
Loaded CA certificate '/etc/ssl/certs/ca-certificates.crt'
Resolving git.thm.de (git.thm.de)... 212.201.6.138
Connecting to git.thm.de (git.thm.de)|212.201.6.138|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 166681 (163K) [application/octet-stream]
Saving to: njc?inline=false.5
0K .......... .......... .......... .......... .......... 30% 1.20M 0s
50K .......... .......... .......... .......... .......... 61% 2.53M 0s
100K .......... .......... .......... .......... .......... 92% 6.70M 0s
150K .......... .. 100% 8.97M=0.07s
2024-01-14 15:07:47 (2.31 MB/s) - njc?inline=false.5 saved [166681/166681]

BIN
njvm-3 Executable file

Binary file not shown.

354
njvm.c
View File

@@ -1,43 +1,345 @@
#include <stdio.h>
#include <string.h>
#include "config.h"
#include "consts.c"
#include "instruktion.c"
#include "code.c"
#include "stack.c"
#include "program.c"
#include "codeReader.c"
#include "SDA.c"
void version() {
printf("Ninja Virtual Machine version %i (compiled %s, %s)\n", PROJECT_VERSION, __DATE__, __TIME__);
// Program
struct program *program;
// SDA
int fp;
int debug = 0;
void version(void) {
printf("Ninja Virtual Machine version %i (compiled %s, %s)\n", VERSION, __DATE__, __TIME__);
}
void help() {
printf("usage: ./njvm [option] [option] ...\n\t--version\tshow version and exit\n\t--help\t\tshow this help and exit");
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");
}
void printArgs(int argc, char *argv[]){
for (int i = 0; i < argc; ++i) {
printf("%s\n", argv[i]);
void execute(struct program *program, struct sda *sda) {
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;
}
}
void useption(int argc, char *argv[]){
if (argc > 1) {
if (strcmp(argv[1], "--version") == 0) {
version();
} else if (strcmp(argv[1], "--help") == 0) {
help();
} else if (argc != 0) {
printf("unknown command line argument '%s', try './njvm --help'", argv[1]);
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;
char charInput;
for (int i = 0; i < program->size; ++i) {
unsigned int instruction = program->program[i];
if (i >= program->size) {
printf("Error: Jump out of program memory\n");
goto end;
}
switch (instruction >> 24) {
case HALT:
goto end;
case PUSHC:
if (debug == 1) printf("PUSHC %d\n", SIGN_EXTEND(IMMEDIATE(instruction)));
push(&stack, SIGN_EXTEND(IMMEDIATE(instruction)));
break;
case ADD:
if (debug == 1) printf("ADD\n");
push(&stack, pop(&stack) + pop(&stack));
break;
case SUB:
tmp = pop(&stack);
if (debug == 1) printf("SUB\n");
if (debug == 1) printf("tmp: %d\n", tmp);
push(&stack, pop(&stack) - tmp);
break;
case MUL:
if (debug == 1) printf("MUL\n");
push(&stack, pop(&stack) * pop(&stack));
break;
case DIV:
tmp = pop(&stack);
if (debug == 1) printf("DIV\n");
if (debug == 1) printf("tmp: %d\n", tmp);
push(&stack, pop(&stack) / tmp);
break;
case MOD:
tmp = pop(&stack);
if (debug == 1) printf("MOD\n");
if (debug == 1) printf("tmp: %d\n", tmp);
push(&stack, pop(&stack) % tmp);
break;
case RDINT:
scanf("%i", &intInput);
if (debug == 1) printf("RDINT %d\n", intInput);
push(&stack, intInput);
break;
case WRINT:
if (debug == 1) printf("WRINT\n");
printf("%i", pop(&stack));
break;
case RDCHR:
scanf("%c", &charInput);
if (debug == 1) printf("RDCHR %c\n", charInput);
push(&stack, charInput);
break;
case WRCHR:
if (debug == 1) printf("WRCHR\n");
printf("%c", pop(&stack));
break;
case PUSHG:
if (debug == 1) printf("PUSHG %d\n", SIGN_EXTEND(IMMEDIATE(instruction)));
currentFrame = stack.frames[stack.currentFrame];
currentFrame->bp = currentFrame->sp;
*currentFrame->sp++ = getSDA(SIGN_EXTEND(IMMEDIATE(instruction)), sda);
break;
case POPG:
if (debug == 1) printf("POPG %d\n", SIGN_EXTEND(IMMEDIATE(instruction)));
currentFrame = stack.frames[stack.currentFrame];
currentFrame->bp = currentFrame->sp;
setSDA(SIGN_EXTEND(IMMEDIATE(instruction)), pop(&stack), sda);
break;
case ASF:
if (debug == 1) printf("ASF %d\n", SIGN_EXTEND(IMMEDIATE(instruction)));
currentFrame = stack.frames[stack.currentFrame];
push(&stack, *currentFrame->sp);
*currentFrame->sp = stack.currentFrame;
currentFrame->bp = currentFrame->sp;
stack.currentFrame += SIGN_EXTEND(IMMEDIATE(instruction));
break;
case RSF:
if (debug == 1) printf("RSF\n");
stack.currentFrame = pop(&stack);
currentFrame = stack.frames[stack.currentFrame];
currentFrame->bp = NULL;
break;
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;
case POPL:
if (debug == 1) printf("POPL %d\n", SIGN_EXTEND(IMMEDIATE(instruction)));
currentFrame = stack.frames[stack.currentFrame];
currentFrame->fp[SIGN_EXTEND(IMMEDIATE(instruction))] = pop(&stack);
break;
case EQ:
if (debug == 1) printf("EQ\n");
if (pop(&stack) == pop(&stack)) {
push(&stack, 1);
} else {
push(&stack, 0);
}
break;
case NE:
if (debug == 1) printf("NE\n");
if (pop(&stack) != pop(&stack)) {
push(&stack, 1);
} else {
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;
case JMP:
if (debug == 1) printf("JMP %d\n", SIGN_EXTEND(IMMEDIATE(instruction)));
int j = SIGN_EXTEND(IMMEDIATE(program->program[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;
case CALL:
tmp = SIGN_EXTEND(IMMEDIATE(program->program[i]));
if (j-- >= program->size) {
printf("Error: Call out of program memory\n");
goto end;
}
push(&callStack, i + 1);
i = tmp;
break;
case RET:
if (debug == 1) printf("RET\n");
tmp = pop(&callStack);
if (tmp-- >= program->size) {
printf("Error: Return out of program memory\n");
goto end;
}
i = tmp;
break;
case DROP:
tmp = SIGN_EXTEND(IMMEDIATE(instruction));
if (debug == 1) printf("DROP %d\n", tmp);
for (int b = 0; b < tmp; ++b) {
pop(&stack);
}
break;
}
}
end:
return;
}
// run prog2.bin
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[]) {
printArgs(argc,argv);
if (argc > 1) useption(argc,argv);
else {
// Initialize the Stack
struct stack stack;
int size = SIZE;
stack.size = size;
stack.currentFrame = 0;
// Started
printf("Ninja Virtual Machine started\n");
// Initialize ProgrammSpeicher
int psize = SIZE;
unsigned int p[1000];
program = malloc(sizeof(struct program));
program->size = psize;
program->program = p;
// Initialize runtime variables
int run = 0;
int sizeSDA;
// Stopped
printf("Ninja Virtual Machine stopped\n");
return 0;
if (argc > 1) {
for (int i = 1; i < argc; ++i) {
if (strcmp(argv[i], "--debug") == 0) {
debug = 1;
} else if (strcmp(argv[i], "--version") == 0) {
version();
return 0;
} else if (strcmp(argv[i], "--help") == 0) {
help();
return 0;
} else {
sizeSDA = fromFile(argv[i], program);
run = 1;
}
}
}
/*
* Debug mode
*/
if (debug) {
tests();
}
/*
* Run program
*/
if (run) {
printf("Ninja Virtual Machine started\n");
struct sda *sda = malloc(sizeof(struct sda));
unsigned int s[sizeSDA];
sda->size = sizeSDA;
sda->sda = s;
if (debug == 1) printProgram(program);
execute(program, (struct sda *) &sda);
printf("Ninja Virtual Machine stopped\n");
} else {
printf("Error: no code file specified\n");
return 1;
}
return 0;
}

120
program.c Normal file
View File

@@ -0,0 +1,120 @@
/*
* Created by Nils on 30.10.2023.
*/
#ifndef PROGRAM
#define PROGRAM
#include <string.h>
#include "instruktion.c"
#include <stdio.h>
struct program {
unsigned int *program;
int size;
};
void copyToProgram(const unsigned int codeToCopy[], int size, struct program *program) {
for (int i = 0; i < size; ++i) {
program->program[i] = codeToCopy[i];
}
program->size = size;
}
void printProgram(struct program *program) {
char c[10];
for (int i = 0; i < program->size; i++) {
switch (program->program[i] >> 24) {
case PUSHC:
strcpy(c, "pushc");
break;
case ADD:
strcpy(c, "add");
break;
case SUB:
strcpy(c, "sub");
break;
case MUL:
strcpy(c, "mul");
break;
case DIV:
strcpy(c, "div");
break;
case MOD:
strcpy(c, "mod");
break;
case RDINT:
strcpy(c, "rdint");
break;
case WRINT:
strcpy(c, "wrint");
break;
case RDCHR:
strcpy(c, "rdchr");
break;
case WRCHR:
strcpy(c, "wrchr");
break;
case HALT:
strcpy(c, "halt");
break;
case PUSHG :
strcpy(c, "pushg");
break;
case POPG:
strcpy(c, "popg");
break;
case ASF:
strcpy(c, "asf");
break;
case RSF:
strcpy(c, "rsf");
break;
case PUSHL:
strcpy(c, "pushl");
break;
case POPL:
strcpy(c, "popl");
break;
case EQ:
strcpy(c,"eq");
break;
case NE:
strcpy(c,"ne");
break;
case LT:
strcpy(c,"lt");
break;
case GT:
strcpy(c,"gt");
break;
case GE:
strcpy(c,"ge");
break;
case JMP:
strcpy(c,"jmp");
break;
case BRF:
strcpy(c, "brf");
break;
case BRT:
strcpy(c,"brt");
break;
case CALL:
strcpy(c,"call");
break;
case RET:
strcpy(c,"ret");
break;
case DROP:
strcpy(c,"drop");
break;
default:
strcpy(c, "ERROR");
break;
}
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);
}
}
#endif /* ifndef PROGRAMM */

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.

31
programs/prog1.asm Normal file
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

BIN
programs/prog1.bin Normal file

Binary file not shown.

33
programs/prog2.asm Normal file
View File

@@ -0,0 +1,33 @@
//
// prog2.asm -- an assembler example with local variables
//
// local Integer x;
// local Integer y;
// x = 2;
// y = x + 3;
// x = 7 * y + x;
// writeInteger(x + -33);
// writeCharacter('\n');
asf 2
pushc 2
popl 0
pushl 0
pushc 3
add
popl 1
pushc 7
pushl 1
mul
pushl 0
add
popl 0
pushl 0
pushc -33
add
wrint
pushc '\n'
wrchr
rsf
halt

BIN
programs/prog2.bin Normal file

Binary file not shown.

61
programs/prog3.asm Normal file
View File

@@ -0,0 +1,61 @@
//
// prog1.asm -- an assembler example with global variables
//
//
// compute the gcd of two positive numbers
//
// 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

BIN
programs/prog3.bin Normal file

Binary file not shown.

63
programs/prog4.asm Normal file
View File

@@ -0,0 +1,63 @@
//
// prog2.asm -- an assembler example with local variables
//
//
// compute the gcd of two positive numbers
//
// local Integer x;
// local Integer y;
// x = readInteger();
// 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
// writeCharacter('\n');
pushc '\n'
wrchr
rsf
halt

BIN
programs/prog4.bin Normal file

Binary file not shown.

35
programs/prog5.asm Normal file
View File

@@ -0,0 +1,35 @@
//
// prog01.asm -- call/ret without args, and without ret value
//
asf 3
pushc 11
wrint
pushc '\n'
wrchr
call proc
pushc 44
wrint
pushc '\n'
wrchr
rsf
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

BIN
programs/prog5.bin Normal file

Binary file not shown.

28
programs/prog6.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

BIN
programs/prog6.bin Normal file

Binary file not shown.

28
programs/prog7.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

BIN
programs/prog7.bin Normal file

Binary file not shown.

48
stack.c Executable file
View File

@@ -0,0 +1,48 @@
//
// Created by Nils on 29.10.2023.
//
#ifndef STACK
#define STACK
#define SIZE 1000
#include <stdio.h>
#include <stdlib.h>
struct stackFrame {
int *fp; // Frame pointer
int *sp; // Stack pointer
int *bp; // Base pointer
};
struct stack {
int size;
int currentFrame;
struct stackFrame *frames[SIZE];
};
void printStack(struct stack *stack) {
printf("Stack:\n");
for (int i = 0; i < stack->size; ++i) {
printf("[%d] = %d\n", i, stack->frames[stack->currentFrame]->sp[i]);
}
}
void push(struct stack *stack, unsigned int value) {
struct stackFrame *currentFrame = stack->frames[stack->currentFrame];
*(currentFrame->sp) = value;
currentFrame->sp++;
}
int pop(struct stack *stack) {
struct stackFrame *currentFrame = stack->frames[stack->currentFrame];
currentFrame->sp--;
return *(currentFrame->sp);
}
int peek(struct stack *stack, int steps) { // peek is pop without removing the value
struct stackFrame *currentFrame = stack->frames[stack->currentFrame];
return *(currentFrame->sp - steps);
}
#endif