complete first homework
This commit is contained in:
parent
2f1c0da937
commit
32f7f00952
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
main.exe
|
23
.vscode/c_cpp_properties.json
vendored
Normal file
23
.vscode/c_cpp_properties.json
vendored
Normal 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
11
.vscode/settings.json
vendored
Normal 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
11
Makefile
Normal 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
|
29
examples/many_register_mov.asm
Normal file
29
examples/many_register_mov.asm
Normal 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
|
19
examples/single_register_mov.asm
Normal file
19
examples/single_register_mov.asm
Normal 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
15
include/os.h
Normal 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
83
src/cpu.c
Normal 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
51
src/main.c
Normal 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;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user