1
0

complete first homework

This commit is contained in:
Rokas Puzonas 2023-04-09 18:32:19 +03:00
parent 2f1c0da937
commit 32f7f00952
9 changed files with 243 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
main.exe

23
.vscode/c_cpp_properties.json vendored Normal file
View File

@ -0,0 +1,23 @@
{
"configurations": [
{
"name": "Win32",
"includePath": [
"${workspaceFolder}/**",
"C:/MinGW/include/**"
],
"defines": [
"_DEBUG",
"UNICODE",
"_UNICODE"
],
"windowsSdkVersion": "10.0.22000.0",
"compilerPath": "C:/MinGW/bin/gcc.exe",
"cStandard": "c17",
"cppStandard": "c++17",
"intelliSenseMode": "windows-gcc-x86",
"configurationProvider": "ms-vscode.makefile-tools"
}
],
"version": 4
}

11
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,11 @@
{
"files.associations": {
"stdlib.h": "c",
"stdio.h": "c",
"os.h": "c",
"fcntl.h": "c",
"io.h": "c",
"errno.h": "c",
"stdbool.h": "c"
}
}

11
Makefile Normal file
View File

@ -0,0 +1,11 @@
CC=gcc
CFLAGS=-g -Wall
INCLUDES=./include
.DEFAULT_GOAL := main
%: src/%.c
$(CC) -o $@ $< $(CFLAGS) -I$(INCLUDES)
clean:
rm main.exe

View File

@ -0,0 +1,29 @@
; ========================================================================
;
; (C) Copyright 2023 by Molly Rocket, Inc., All Rights Reserved.
;
; This software is provided 'as-is', without any express or implied
; warranty. In no event will the authors be held liable for any damages
; arising from the use of this software.
;
; Please see https://computerenhance.com for further information
;
; ========================================================================
; ========================================================================
; LISTING 38
; ========================================================================
bits 16
mov cx, bx
mov ch, ah
mov dx, bx
mov si, bx
mov bx, di
mov al, cl
mov ch, ch
mov bx, ax
mov bx, si
mov sp, di
mov bp, ax

View File

@ -0,0 +1,19 @@
; ========================================================================
;
; (C) Copyright 2023 by Molly Rocket, Inc., All Rights Reserved.
;
; This software is provided 'as-is', without any express or implied
; warranty. In no event will the authors be held liable for any damages
; arising from the use of this software.
;
; Please see https://computerenhance.com for further information
;
; ========================================================================
; ========================================================================
; LISTING 37
; ========================================================================
bits 16
mov cx, bx

15
include/os.h Normal file
View File

@ -0,0 +1,15 @@
#if defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__)
#define IS_WINDOWS
#elif defined(__linux__)
#define IS_LINUX
#else
#error Unable to determine platform
#endif
#if defined(IS_LINUX)
#include <stdio.h>
#define MAX_PATH_SIZE PATH_MAX
#elif defined(IS_WINDOWS)
#define MAX_PATH_SIZE 260
#endif

83
src/cpu.c Normal file
View File

@ -0,0 +1,83 @@
#include <inttypes.h>
#include <stdio.h>
#include <stdbool.h>
#define u32 uint32_t
#define u16 uint16_t
#define u8 uint8_t
struct cpu_state {
u16 ax, bx, cx, dx, sp, bp, si, di;
};
const char *lookup_reg_name(u8 idx, bool wide) {
if (wide) {
if (idx == 0b000) {
return "ax";
} else if (idx == 0b001) {
return "cx";
} else if (idx == 0b010) {
return "dx";
} else if (idx == 0b011) {
return "bx";
} else if (idx == 0b100) {
return "sp";
} else if (idx == 0b101) {
return "bp";
} else if (idx == 0b110) {
return "si";
} else if (idx == 0b111) {
return "di";
}
} else {
if (idx == 0b000) {
return "al";
} else if (idx == 0b001) {
return "cl";
} else if (idx == 0b010) {
return "dl";
} else if (idx == 0b011) {
return "bl";
} else if (idx == 0b100) {
return "ah";
} else if (idx == 0b101) {
return "ch";
} else if (idx == 0b110) {
return "dh";
} else if (idx == 0b111) {
return "bh";
}
}
printf("ERROR: Unknown register %d, wide %d", idx, wide);
abort();
}
void dissassemble(FILE *src, FILE *dst) {
fprintf(dst, "bits 16\n\n");
while (!feof(src)) {
u8 byte1 = fgetc(src);
u8 byte2 = fgetc(src);
if ((byte1 & 0b11111100) == 0b10001000) {
bool wide = byte1 & 0b1;
bool direction = (byte1 & 0b10) >> 1;
u8 mod = byte2 & 0b11000000;
u8 reg = (byte2 & 0b00111000) >> 3;
u8 rm = byte2 & 0b00000111;
if (mod == 0b11000000) {
const char *reg_name = lookup_reg_name(reg, wide);
const char *rm_name = lookup_reg_name(rm, wide);
if (direction) {
fprintf(dst, "mov %s, %s\n", reg_name, rm_name);
} else {
fprintf(dst, "mov %s, %s\n", rm_name, reg_name);
}
} else {
printf("ERROR: Unsupported mod '%d'", mod);
abort();
}
}
}
}

51
src/main.c Normal file
View File

@ -0,0 +1,51 @@
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include "os.h"
#include "cpu.c"
#include <errno.h>
const char *get_tmp_dir() {
#ifdef IS_WINDOWS
char *dir;
if ((dir = getenv("TMPDIR")) != NULL) return dir;
if ((dir = getenv("TEMP")) != NULL) return dir;
if ((dir = getenv("TMP")) != NULL) return dir;
return NULL;
#elif IS_LINUX
return "/tmp";
#endif
}
void get_tmp_file(char *filename, const char *prefix) {
const char *dir = get_tmp_dir();
sprintf(filename, "%s\\%sXXXXXX", dir, prefix);
int fd = mkstemp(filename);
close(fd);
}
int main() {
char tmp_filename[MAX_PATH_SIZE];
get_tmp_file(tmp_filename, "nasm_output");
char *example_filename = "examples/many_register_mov.asm";
char command[512] = { 0 };
snprintf(command, sizeof(command), "nasm \"%s\" -o \"%s\"", example_filename, tmp_filename);
if (system(command)) {
printf("ERROR: Failed to compile '%s'", example_filename);
return -1;
}
FILE *assembly = fopen(tmp_filename, "r");
if (assembly == NULL) {
printf("ERROR: Opening file '%s': %d\n", tmp_filename, errno);
return -1;
}
dissassemble(assembly, stdout);
fclose(assembly);
remove(tmp_filename);
return 0;
}