This commit is contained in:
anon
2024-07-19 04:11:05 +02:00
5 changed files with 419 additions and 472 deletions

View File

@ -1,525 +1,492 @@
#include "assembler.h" #include "assembler.h"
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
#define REGULAR_BEGIN (ADD) #define REGULAR_BEGIN (ADD)
#define REGULAR_END (CMP) #define REGULAR_END (CMP)
#define IRREGULAR_BEGIN (INC) #define IRREGULAR_BEGIN (INC)
#define IRREGULAR_END (IDIV) #define IRREGULAR_END (IDIV)
#define SPECIAL_1_BEGIN (NOP) #define SPECIAL_1_BEGIN (NOP)
#define SPECIAL_1_END (PUSHF) #define SPECIAL_1_END (WAIT)
#define SPECIAL_2_BEGIN (SYSENTER) #define SPECIAL_2_BEGIN (SYSENTER)
#define SPECIAL_2_END (EMMS) #define SPECIAL_2_END (FCOS)
#define JUMP_IF_BEGIN (JO) #define JUMP_IF_BEGIN (JO)
#define JUMP_IF_END (JG) #define JUMP_IF_END (JG)
#define MOVE_IF_BEGIN (CMOVO) #define MOVE_IF_BEGIN (CMOVO)
#define MOVE_IF_END (CMOVG) #define MOVE_IF_END (CMOVG)
#define FLOAT_BEGIN (FADD)
#define REGULAR_COUNT (REGULAR_END - REGULAR_BEGIN + 1) // 16 #define FLOAT_END (FDIVR)
#define IRREGULAR_COUNT (IRREGULAR_END - IRREGULAR_BEGIN + 1) // 16
#define SPECIAL_1_COUNT (SPECIAL_1_END - SPECIAL_1_BEGIN + 1) // 8
#define SPECIAL_2_COUNT (SPECIAL_2_END - SPECIAL_2_BEGIN + 1) // 6
#define JUMP_IF_COUNT (JUMP_IF_END - JUMP_IF_BEGIN + 1) // 16
#define MOVE_IF_COUNT (MOVE_IF_END - MOVE_IF_BEGIN + 1) // 16
static int assemble_clean_up_queued = 0; static int assemble_clean_up_queued = 0;
static next empty_count = 0; static unsigned int empty_count = 0;
static next empty_holes = 0; static unsigned int empty_holes = 0;
static next * empty_array = NULL; static unsigned int * empty_array = NULL;
static next * empty_imbue = NULL; static unsigned int * empty_imbue = NULL;
static next * empty_store = NULL; static unsigned int * empty_store = NULL;
static void input (form when, static void replace(unsigned char * destination,
byte data) { unsigned char * source,
// Input one byte to text sector. unsigned long size) {
text_sector_byte [text_sector_size] = data; while (--size) {
destination [size] = source [size];
text_sector_size += (next) when; }
} }
static void input_by (form when, static void input(int when, unsigned int data) {
size_index size, text_sector_byte[text_sector_size] = (unsigned char) data;
next data) {
// Input size-dependent bytes to text sector. text_sector_size += (unsigned int) when;
input ((when != 0) && (size >= D8), (byte) ((data >> 0) & 0xff));
input ((when != 0) && (size >= D16), (byte) ((data >> 8) & 0xff));
input ((when != 0) && (size >= D32), (byte) ((data >> 16) & 0xff));
input ((when != 0) && (size >= D32), (byte) ((data >> 24) & 0xff));
// 64-BIT SUPPORT
} }
static void asmdirrel (form when, static void input_by(int when, unsigned int size, unsigned int data) {
next data) { input((when), (data >> 0) & 0xff);
// Assembler directive, queue relative memory address. input((when) && (size >= D16), (data >> 8) & 0xff);
empty_array [empty_holes] = text_sector_size; input((when) && (size >= D32), (data >> 16) & 0xff);
empty_imbue [empty_holes] = data; input((when) && (size >= D32), (data >> 24) & 0xff);
empty_holes += (next) when;
} }
static void asmdirmem (form when, static void asmdirrel(int when, unsigned int data) {
next code) { empty_array[empty_holes] = text_sector_size;
// Assembler directive, queue memory address. empty_imbue[empty_holes] = data;
empty_store [code] = text_sector_size;
empty_count += (next) when; empty_holes += (unsigned int) when;
} }
static void asmdirimm (form when, static void asmdirmem(int when, unsigned int code) {
size_index size, empty_store[code] = text_sector_size;
next data) {
// Assembler directive, queue immediate value at current size. empty_count += (unsigned int) when;
input_by (when, size, data);
} }
static void input_at (form when, static void asmdirimm(int when, unsigned int size, unsigned int data) {
size_index size, input_by(when, size, data);
next data,
next base) {
// Input relative memory address to text sector.
asmdirrel (when, data);
input ((when != 0) && (size >= D8), (byte) ((base >> 0) & 0xff));
input ((when != 0) && (size >= D16), (byte) ((base >> 8) & 0xff));
input ((when != 0) && (size >= D32), (byte) ((base >> 16) & 0xff));
input ((when != 0) && (size >= D32), (byte) ((base >> 24) & 0xff));
// NO DEREFERENCING
// 64-BIT SUPPORT
} }
static form front (form data) { return ((data >= 4) && (data <= 7)); } static void input_at(int when, unsigned int size, unsigned int data, unsigned int base) {
static form lower (form data) { return ((data >= 0) && (data <= 7)); } asmdirrel(when, data);
static form upper (form data) { return ((data >= 8) && (data <= 15)); }
static form far (next label) { return (label && 1); } // Unused for now. input((when), ((base >> 0) & 0xff));
static form near (next label) { return (label && 0); } // Unused for now. input((when) && (size >= D16), ((base >> 8) & 0xff));
input((when) && (size >= D32), ((base >> 16) & 0xff));
static void build_short_prefix (form when) { input((when) && (size >= D32), ((base >> 24) & 0xff));
// 66
input (when, 0x66);
} }
static void build_long_prefix (form big_registers, static int front(unsigned int data) { return ((data >= 4) && (data <= 7)); }
form new_destination, static int lower(unsigned int data) { return ( (data <= 7)); }
form new_source) { static int upper(unsigned int data) { return ((data >= 8) && (data <= 15)); }
// 40-4D!0X02
input (big_registers || new_destination || new_source, static int far(unsigned int label) { return (label && 1); }
(byte) (0x40 static int near(unsigned int label) { return (label && 0); }
+ 0x01 * new_destination
+ 0x04 * new_source static void build_short (int when) {
+ 0x08 * big_registers)); input(when, 0x66);
} }
static void build_register_direction (form when, static void build_long(int registers, unsigned int to, unsigned int from) {
next destination, input(registers || to || from, 0x40
next source) { + 0x01 * (unsigned int) to
// C0-FF + 0x04 * (unsigned int) from
input (when, + 0x08 * (unsigned int) registers);
(byte) (0xc0
+ 0x01 * (destination & 0x07)
+ 0x08 * (source & 0x07)));
} }
static void build_register_redirection (form when, static void build_co(int when, unsigned int destination, unsigned int source) {
next direction) { input(when, 0xc0
// 05-3D + 0x01 * (destination & 0x07)
input (when, + 0x08 * (source & 0x07));
(byte) (0x05
+ 0x08 * (direction & 0x07)));
} }
static void build_constant (form when, static void build_at(int when, unsigned int direction) {
size_index size) { input(when, 0x05
// 80/81 + 0x08 * (direction & 0x07));
input (when,
(byte) (0x80
+ 0x01 * (size != D8)));
} }
static void build_regular (operation_index operation, static void build_constant(int when, unsigned int size) {
size_index size, input(when, 0x80
type_index to, + 0x01 * (size != D8));
next destination,
type_index from,
next source) {
// 00-3F : add, or, adc, sbb, and, sub, xor, cmp;
build_short_prefix (size == D16);
build_long_prefix (size == D64,
(to == REG) && (upper ((form) destination)),
(from == REG) && (upper ((form) source)));
input ((size == D8)
&& (to == REG)
&& ((from == REG) || (from == IMM))
&& (((front ((form) destination) && lower ((form) source)) //
|| (lower ((form) destination) && front ((form) source))) //
|| ((to == REG) && (from == IMM) && front ((form) destination))),
(byte) 0x40);
input ((from == IMM) && (to == REG) && (destination == 0),
(byte) (0x05
+ 0x08 * (operation & 0x07))
- 0x01 * (size == D8));
build_constant ((from == IMM) && ! ((to == REG) && (destination == 0)),
size);
input (! ((from == IMM) && (to == REG) && (destination == 0)),
(byte) (0x08 * (operation - REGULAR_BEGIN)
+ 0x01 * ((to == MEM) && (from == IMM) && (size == D8))
- 0x01 * ((to == REG) && (from == IMM) && (size != D8))
+ 0x01 * (size != D8)
+ 0x02 * ((to == REG) && (from == MEM))
+ 0x04 * ((to == MEM) && (from == IMM))
+ 0xc0 * ((to == REG) && (from == IMM)))
+ (destination & 0x07) * ((to == REG) && (from == IMM)));
build_register_direction ((to == REG) && (from == REG),
destination, source);
build_register_redirection ((to == REG) && (from == MEM), destination);
build_register_redirection ((to == MEM) && (from == REG), source);
input_by ((to == REG) && (from == MEM), D32, (next) ~0);
input_by ((to == REG) && (from == IMM), size, source);
input_by ((to == MEM) && (from == REG), D32, (next) ~0);
input_by ((to == MEM) && (from == IMM), D32, (next) ~0);
input_by ((to == MEM) && (from == IMM), size, source);
} }
static void build_irregular (operation_index operation, static void build_regular(unsigned int operation,
size_index size, unsigned int size,
type_index to, unsigned int to,
next destination) { unsigned int destination,
// F0-FF : inc, dec, not, neg, mul, imul, div, idiv; unsigned int from,
build_short_prefix (size == D16); unsigned int source) {
build_short(size == D16);
build_long_prefix (size == D64, build_long(size == D64,
(to == REG) && (upper ((form) destination)), 0); (to == REG) && (upper(destination)),
(from == REG) && (upper(source)));
input ((size == D8) && (to == REG) && front ((form) destination), input((size == D8) && (to == REG) && ((from == REG) || (from == IMM))
(byte) 0x40); && (((front(destination) && lower(source))
|| (lower(destination) && front(source)))
|| ((to == REG) && (from == IMM) && front(destination))),
0x40);
input (1, input((from == IMM) && (to == REG) && (destination == 0), 0x05
(byte) (0xf7 + 0x08 * (operation & 0x07)
+ 0x08 * ((operation == INC) || (operation == DEC)) - 0x01 * (size == D8));
- 0x01 * (size == D8)));
input (to == REG, build_constant((from == IMM) && ! ((to == REG) && (destination == 0)),
(byte) (0xc0 size);
+ 0x08 * (operation - IRREGULAR_BEGIN))
+ 0x01 * (destination & 0x07));
input (to == MEM, input(! ((from == IMM) && (to == REG) && (destination == 0)),
(byte) (0x05 (destination & 0x07) * ((to == REG) && (from == IMM))
+ 0x08 * (operation - IRREGULAR_BEGIN))); + 0x08 * (operation - REGULAR_BEGIN)
+ 0x01 * ((to == MEM) && (from == IMM) && (size == D8))
- 0x01 * ((to == REG) && (from == IMM) && (size != D8))
+ 0x01 * (size != D8)
+ 0x02 * ((to == REG) && (from == MEM))
+ 0x04 * ((to == MEM) && (from == IMM))
+ 0xc0 * ((to == REG) && (from == IMM)));
build_co((to == REG) && (from == REG), destination, source);
build_at((to == REG) && (from == MEM), destination);
build_at((to == MEM) && (from == REG), source);
input_by((to == REG) && (from == MEM), D32, ~0x0u);
input_by((to == REG) && (from == IMM), size, source);
input_by((to == MEM) && (from == REG), D32, ~0x0u);
input_by((to == MEM) && (from == IMM), D32, ~0x0u);
input_by((to == MEM) && (from == IMM), size, source);
} }
static void build_special_1 (operation_index operation) { static void build_irregular(unsigned int operation,
// XX : nop, retn, retf, leave, lock, hlt, popf, pushf; unsigned int size,
const byte data [1 * SPECIAL_1_COUNT] = { unsigned int to,
0x90, 0xc3, 0xcb, 0xc9, 0xf0, 0xf4, 0x9d, 0x9c unsigned int destination) {
build_short(size == D16);
build_long(size == D64,
(to == REG) && (upper(destination)), 0);
input((size == D8) && (to == REG) && front(destination), 0x40);
input(1, 0xf7
+ 0x08 * ((operation == INC) || (operation == DEC))
- 0x01 * (size == D8));
input(to == REG, 0xc0
+ 0x08 * (operation - IRREGULAR_BEGIN)
+ 0x01 * (destination & 0x07));
input(to == MEM, 0x05
+ 0x08 * (operation - IRREGULAR_BEGIN));
}
static void build_special_1(unsigned int operation) {
const unsigned char data [SPECIAL_1_END - SPECIAL_1_BEGIN + 1] = {
0x90, 0xc3, 0xcb, 0xc9, 0xf0, 0xf4, 0x9d, 0x9c,
0x9b
}; };
input (1, data [operation - SPECIAL_1_BEGIN]); input(1, data[operation - SPECIAL_1_BEGIN]);
} }
static void build_special_2 (operation_index operation) { static void build_special_2(unsigned int operation) {
// XX XX : sysenter, sysleave, syscall, sysret, pause, cpuid, emms; const unsigned char data [2 * (SPECIAL_2_END - SPECIAL_2_BEGIN + 1)] = {
const byte data [2 * SPECIAL_2_COUNT] = { 0x0f, 0x0f, 0x0f, 0x0f, 0xf3, 0x0f, 0x0f, 0x0f,
0x0f, 0x0f, 0x0f, 0x0f, 0xf3, 0x0f, 0x0f, 0xd9, 0xd9, 0xd9, 0xd9, 0xd9, 0xd9, 0xd9, 0xd9,
0x34, 0x35, 0x05, 0x07, 0x90, 0xa2, 0x77 0xd9, 0xd9, 0xd9, 0xd9, 0xd9, 0xd9, 0xd9, 0xd9,
0xd9, 0xd9, 0xd9, 0xd9, 0xd9, 0xd9, 0xd9, 0xd9,
0xd9, 0xd9, 0xd9, 0xd9,
0x34, 0x35, 0x05, 0x07, 0x90, 0xa2, 0x77, 0xaa,
0xd0, 0xe0, 0xe1, 0xe4, 0xe5, 0xe8, 0xe9, 0xea,
0xeb, 0xec, 0xed, 0xee, 0xf0, 0xf1, 0xf2, 0xf3,
0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb,
0xfc, 0xfd, 0xfe, 0xff
}; };
input (1, data [operation - SPECIAL_2_BEGIN]); input(1, data[operation - 1 * SPECIAL_2_BEGIN]);
input (1, data [operation - SPECIAL_2_BEGIN + SPECIAL_2_COUNT]); input(1, data[operation - 2 * SPECIAL_2_BEGIN + SPECIAL_1_END + 1]);
} }
static void build_jump_if (operation_index operation, static void build_jump_if(unsigned int operation,
size_index size, unsigned int size,
next location) { unsigned int location) {
// j** input(far(location) && (size == D32), 0x0f);
(void) size; // For now, everything is a far jump.
input (far (location), 0x0f); input(far(location), 0x80 + operation - JUMP_IF_BEGIN);
input (far (location), (byte) (0x80 + operation - JUMP_IF_BEGIN)); input(near(location), 0x70 + operation - JUMP_IF_BEGIN);
input (near (location), (byte) (0x70 + operation - JUMP_IF_BEGIN));
// displacement (4, 0X12345678);
} }
static void build_move_if (operation_index operation, static void build_move_if(unsigned int operation,
size_index size, unsigned int size,
type_index to, unsigned int to,
next destination, unsigned int destination,
type_index from, unsigned int from,
next source) { unsigned int source) {
// cmov** build_short(size == D16);
build_short_prefix (size == D16);
build_long_prefix (size == D64, build_long(size == D64,
(to == REG) && (upper ((form) destination)), (to == REG) && (upper(destination)),
(from == REG) && (upper ((form) source))); (from == REG) && (upper(source)));
input (1, 0x0f); input(1, 0x0f);
input (1, (byte) (0x40 + operation - MOVE_IF_BEGIN)); input(1, 0x40 + operation - MOVE_IF_BEGIN);
build_register_direction ((to == REG) && (from == REG), build_co((to == REG) && (from == REG), destination, source);
destination, source); build_at((to == REG) && (from == MEM), destination);
build_register_redirection ((to == REG) && (from == MEM), destination);
// displacement (4, 0X12345678); // Not implemented at this point!
} }
static void build_jump (size_index size, static void build_jump(unsigned int size,
type_index to, unsigned int to,
next destination) { unsigned int destination) {
// jmp input((to == REG) && upper(destination), 0X41);
input ((to == REG) && upper ((form) destination), (byte) 0X41);
input (to == REL, (byte) (0xe9 + 0x02 * (size == D8))); input(to == REL, 0xe9 + 0x02 * (size == D8));
input (to == REG, (byte) 0xff); input(to == REG, 0xff);
input (to == REG, (byte) (0xe0 + 0x01 * (destination & 0x07))); input(to == REG, 0xe0 + 0x01 * (destination & 0x07));
input (to == MEM, (byte) 0xff); input(to == MEM, 0xff);
input (to == MEM, (byte) 0x25); input(to == MEM, 0x25);
// displacement (to == MEM, 4, 0x12345678); // Keep when in mind!
} }
static void build_move (size_index size, static void build_move(unsigned int size,
type_index to, unsigned int to,
next destination, unsigned int destination,
type_index from, unsigned int from,
next source) { unsigned int source) {
// mov build_short(size == D16);
build_short_prefix (size == D16);
build_long_prefix (size == D64, build_long(size == D64,
(to == REG) && (upper ((form) destination)), (to == REG) && (upper(destination)),
(from == REG) && (upper ((form) source))); (from == REG) && (upper(source)));
input ((to == REG) && (from == REG), (byte) (0x88 + (size != D8))); input((to == REG) && (from == REG), 0x88 + (size != D8));
input ((to == REG) && (from == MEM), (byte) (0x8a + (size != D8))); input((to == REG) && (from == MEM), 0x8a + (size != D8));
input ((to == MEM) && (from == REG), (byte) (0x88 + (size != D8))); input((to == MEM) && (from == REG), 0x88 + (size != D8));
build_register_redirection ((to == REG) && (from == MEM), destination); build_at((to == REG) && (from == MEM), destination);
build_register_redirection ((to == MEM) && (from == REG), source); build_at((to == MEM) && (from == REG), source);
input ((to == REG) && ((from == IMM) || (from == REL)), input((to == REG) && ((from == IMM) || (from == REL)), 0xb8
(byte) (0xb8 + 0x01 * (destination & 0x07));
// + 0x08 * (size != D8)
+ 0x01 * (destination & 0x07)));
input ((to == MEM) && (from == IMM), (byte) (0xc6 + (size != D8))); input((to == MEM) && (from == IMM), 0xc6 + (size != D8));
input ((to == MEM) && (from == IMM), (byte) (0x05)); input((to == MEM) && (from == IMM), 0x05);
input_at ((to == REG) && (from == MEM), D32, source, 0); input_at((to == REG) && (from == MEM), D32, source, 0);
input_by ((to == REG) && (from == IMM), size, source); input_by((to == REG) && (from == IMM), size, source);
input_at ((to == MEM) && (from == REG), D32, (next) ~0, (next) ~0); input_at((to == MEM) && (from == REG), D32, ~0x0u, ~0x0u);
input_at ((to == MEM) && (from == IMM), D32, (next) ~0, (next) ~0); input_at((to == MEM) && (from == IMM), D32, ~0x0u, ~0x0u);
input_by ((to == MEM) && (from == IMM), size, source); input_by((to == MEM) && (from == IMM), size, source);
input_at ((to == REG) && (from == REL), D32, source, 0x4010b0); input_at((to == REG) && (from == REL), D32, source, 0x4010b0);
} }
static void build_call (type_index from, static void build_call(unsigned int from,
next source) { unsigned int source) {
// call input((from == REG) && (upper(source)), 0x41);
input ((from == REG) && (upper ((form) source)), (byte) 0x41);
input (from == REL, (byte) 0xe8); input(from == REL, 0xe8);
input (from == REG, (byte) 0xff); input(from == REG, 0xff);
input_at (from == REL, D32, source, (next) -(text_sector_size + 4)); input_at(from == REL, D32, source, -(text_sector_size + 4));
input (from == REG, (byte) (0xd0 + 0x01 * (source & 0x07))); input(from == REG, (0xd0 + 0x01 * (source & 0x07)));
} }
static void build_enter (next dynamic_storage, static void build_enter(unsigned int dynamic_storage,
next nesting_level) { unsigned int nesting_level) {
// enter input(1, 0xc8);
input (1, (byte) 0xc8);
input_by (1, D16, dynamic_storage); input_by(1, D16, dynamic_storage);
input_by (1, D8, nesting_level & (next) 0x1f); input_by(1, D8, nesting_level & 0x1f);
} }
static void build_in_out (form move, static void build_in_out(unsigned int move,
size_index size, unsigned int size,
type_index type, unsigned int type,
next port) { unsigned int port) {
// E4-EF : in, out; build_short(size == D16);
build_short_prefix (size == D16);
input (1, input(1, 0xe4
(byte) 0xe4 + 0x01 * (size != D8)
+ 0x01 * (size != D8) + 0x02 * (move != OUT)
+ 0x02 * (move != OUT) + 0x08 * (type == REG));
+ 0x08 * (type == REG));
input_by (type == IMM, D8, port); input_by(type == IMM, D8, port);
} }
static void build_pop (size_index size, static void build_pop(unsigned int size,
type_index to, unsigned int to,
next destination) { unsigned int destination) {
// pop build_short(size == D16);
build_short_prefix (size == D16);
input ((to == REG) && (upper ((form) destination)), (byte) 0x41); input((to == REG) && (upper(destination)), 0x41);
input (to == REG, (byte) (0x58 + 0x01 * (destination & 0x07))); input(to == REG, 0x58 + 0x01 * (destination & 0x07));
input (to == MEM, (byte) 0x8f); input(to == MEM, 0x8f);
input (to == MEM, (byte) 0x05); input(to == MEM, 0x05);
input_at (to == MEM, D32, destination, 0); input_at(to == MEM, D32, destination, 0);
} }
static void build_push (size_index size, static void build_push(unsigned int size,
type_index from, unsigned int from,
next source) { unsigned int source) {
// push build_short(size == D16);
build_short_prefix (size == D16);
input ((from == REG) && (upper ((form) source)), (byte) 0x41); input((from == REG) && (upper(source)), 0x41);
input (from == REG, (byte) (0x50 + 0x01 * (source & 0x07))); input(from == REG, 0x50 + 0x01 * (source & 0x07));
input (from == MEM, (byte) 0xff); input(from == MEM, 0xff);
input (from == MEM, (byte) 0x35); input(from == MEM, 0x35);
input (from == IMM, (byte) 0x68 + 0x02 * (size == D8)); input(from == IMM, 0x68 + 0x02 * (size == D8));
input_at (from == MEM, D32, source, 0); input_at(from == MEM, D32, source, 0);
input_by (from == IMM, size, source); input_by(from == IMM, size, source);
}
static void build_float(unsigned int operation,
unsigned int size,
unsigned int from,
unsigned int source) {
input(from == MEM, 0xd8 + 0x04 * (size == D64));
build_at(from == MEM, operation);
input_at(from == MEM, size, source, 0);
} }
static void assemble_clean_up (void) { static void assemble_clean_up (void) {
if (assemble_clean_up_queued == 0) { if (!assemble_clean_up_queued) {
return; return;
} }
free (text_sector_byte); free(text_sector_byte);
free (empty_array); free(empty_array);
free (empty_imbue); free(empty_imbue);
free (empty_store); free(empty_store);
} }
next text_sector_size = 0; unsigned int text_sector_size = 0;
byte * text_sector_byte = NULL; unsigned char * text_sector_byte = NULL;
int was_instruction_array_empty = 0; int was_instruction_array_empty = 0;
unsigned int text_entry_point = 0; unsigned int text_entry_point = 0;
void assemble (next count, void assemble(unsigned int count,
next * array) { unsigned int * array) {
// Main batched assembling procedure. unsigned int index = 0;
next index;
if ((count == 0) || (array == NULL)) { if ((count == 0) || (array == NULL)) {
was_instruction_array_empty = 1; was_instruction_array_empty = 1;
return; return;
} }
// Right now, batching is not supported, it will be soon. text_sector_byte = calloc(1440UL, sizeof(* text_sector_byte));
// In that case, realloc function will be used with memset. empty_array = calloc(144UL, sizeof(* empty_array));
text_sector_byte = calloc (1440UL, sizeof (* text_sector_byte)); empty_imbue = calloc(144UL, sizeof(* empty_imbue));
empty_array = calloc (144UL, sizeof (* empty_array)); empty_store = calloc(144UL, sizeof(* empty_store));
empty_imbue = calloc (144UL, sizeof (* empty_imbue));
empty_store = calloc (144UL, sizeof (* empty_store));
if (assemble_clean_up_queued == 0) { if (!assemble_clean_up_queued) {
atexit (assemble_clean_up); atexit(assemble_clean_up);
assemble_clean_up_queued = ! assemble_clean_up_queued; assemble_clean_up_queued = !assemble_clean_up_queued;
} }
for (index = 0; index < count; ++index) { while (index < count) {
if (array [index] == ASMDIRREL) { if (array[index] == ASMDIRREL) {
asmdirrel (1, array [index + 1]); asmdirrel(1, array[index + 1]);
index += 1; index += 1;
} else if (array [index] == ASMDIRMEM) { } else if (array[index] == ASMDIRMEM) {
asmdirmem (1, array [index + 1]); asmdirmem(1, array[index + 1]);
index += 1; index += 1;
} else if (array [index] == ASMDIRIMM) { } else if (array[index] == ASMDIRIMM) {
next repeat; unsigned int repeat = 0;
for (repeat = 0; repeat < array [index + 2]; ++repeat) { while (repeat < array[index + 2]) {
asmdirimm (1, array [index + 1], asmdirimm(1, array[index + 1],
array [index + 3 + repeat]); array[index + 3 + repeat]);
++repeat;
} }
index += 2 + array [index + 2]; index += array[index + 2] + 2;
// } else if (array [index] == ASMDIRREP) { } else if ((array[index] >= REGULAR_BEGIN)
} else if ((array [index] >= REGULAR_BEGIN) && (array[index] <= REGULAR_END)) {
&& (array [index] <= REGULAR_END)) { build_regular(array[index + 0], array[index + 1],
build_regular (array [index + 0], array [index + 1], array[index + 2], array[index + 3],
array [index + 2], array [index + 3], array[index + 4], array[index + 5]);
array [index + 4], array [index + 5]);
index += 5; index += 5;
} else if ((array [index] >= IRREGULAR_BEGIN) } else if ((array[index] >= IRREGULAR_BEGIN)
&& (array [index] <= IRREGULAR_END)) { && (array[index] <= IRREGULAR_END)) {
build_irregular (array [index + 0], array [index + 1], build_irregular(array[index + 0], array[index + 1],
array [index + 2], array [index + 3]); array[index + 2], array[index + 3]);
index += 3; index += 3;
} else if ((array [index] >= SPECIAL_1_BEGIN) } else if ((array[index] >= SPECIAL_1_BEGIN)
&& (array [index] <= SPECIAL_1_END)) { && (array[index] <= SPECIAL_1_END)) {
build_special_1 (array [index + 0]); build_special_1(array[index + 0]);
index += 0; index += 0;
} else if ((array [index] >= SPECIAL_2_BEGIN) } else if ((array[index] >= SPECIAL_2_BEGIN)
&& (array [index] <= SPECIAL_2_END)) { && (array[index] <= SPECIAL_2_END)) {
build_special_2 (array [index + 0]); build_special_2(array[index + 0]);
index += 0; index += 0;
} else if ((array [index] >= JUMP_IF_BEGIN) } else if ((array[index] >= JUMP_IF_BEGIN)
&& (array [index] <= JUMP_IF_END)) { && (array[index] <= JUMP_IF_END)) {
build_jump_if (array [index + 0], array [index + 1], build_jump_if(array[index + 0], array[index + 1],
array [index + 2]); array[index + 2]);
index += 2; index += 2;
} else if ((array [index] >= MOVE_IF_BEGIN) } else if ((array[index] >= MOVE_IF_BEGIN)
&& (array [index] <= MOVE_IF_END)) { && (array[index] <= MOVE_IF_END)) {
build_move_if (array [index + 0], array [index + 1], build_move_if(array[index + 0], array[index + 1],
array [index + 2], array [index + 3], array[index + 2], array[index + 3],
array [index + 4], array [index + 5]); array[index + 4], array[index + 5]);
index += 5; index += 5;
} else if (array [index] == JMP) { } else if ((array[index] >= FLOAT_BEGIN)
build_jump (array [index + 1], array [index + 2], && (array[index] <= FLOAT_END)) {
array [index + 3]); build_float(array[index + 0], array[index + 1],
array[index + 2], array[index + 3]);
index += 3; index += 3;
} else if (array [index] == MOV) { } else if (array[index] == JMP) {
build_move (array [index + 1], array [index + 2], build_jump(array[index + 1], array[index + 2],
array [index + 3], array [index + 4], array[index + 3]);
array [index + 5]); index += 3;
} else if (array[index] == MOV) {
build_move(array[index + 1], array[index + 2],
array[index + 3], array[index + 4],
array[index + 5]);
index += 5; index += 5;
} else if (array [index] == CALL) { } else if (array[index] == CALL) {
build_call (array [index + 1], array [index + 2]); build_call(array[index + 1], array[index + 2]);
index += 2; index += 2;
} else if (array [index] == ENTER) { } else if (array[index] == ENTER) {
build_enter (array [index + 1], array [index + 2]); build_enter(array[index + 1], array[index + 2]);
index += 2; index += 2;
} else if ((array [index] == IN) || (array [index] == OUT)) { } else if ((array[index] == IN) || (array[index] == OUT)) {
build_in_out (array [index + 0], array [index + 1], build_in_out(array[index + 0], array[index + 1],
array [index + 2], array [index + 3]); array[index + 2], array[index + 3]);
index += 3; index += 3;
} else if (array [index] == POP) { } else if (array[index] == POP) {
build_pop (array [index + 1], array [index + 2], build_pop(array[index + 1], array[index + 2],
array [index + 3]); array[index + 3]);
index += 3; index += 3;
} else if (array [index] == PUSH) { } else if (array[index] == PUSH) {
build_push (array [index + 1], array [index + 2], build_push(array[index + 1], array[index + 2],
array [index + 3]); array[index + 3]);
index += 3; index += 3;
} else { } else {
return; return;
} }
++index;
} }
text_entry_point = empty_store [0]; text_entry_point = empty_store [0];
for (index = 0; index < empty_holes; ++index) { index = 0;
next set = 0, get = empty_array [index];
memcpy (& set, & text_sector_byte [get], sizeof (set)); while (index < empty_holes) {
unsigned int set = 0;
unsigned int get = empty_array[index];
set += empty_store [empty_imbue [index]]; replace((unsigned char *) & set,
& text_sector_byte[get],
sizeof (set));
memcpy (& text_sector_byte [get], & set, sizeof (set)); set += empty_store[empty_imbue[index]];
replace(& text_sector_byte[get],
(unsigned char *) & set,
sizeof (set));
++index;
} }
} }

View File

@ -1,52 +1,42 @@
#ifndef ASSEMBLER_H #ifndef ASSEMBLER_H
typedef signed int form; enum {
typedef unsigned int next; D8, D16, D32, D64
typedef unsigned char byte; };
typedef enum { enum {
D8 = 0, REL, REG, MEM, IMM
D16 = 1, };
D32 = 2,
D64 = 3,
} size_index;
typedef enum { enum {
REL, REG, MEM, IMM, ASMDIRMEM, ASMDIRREL, ASMDIRIMM, ASMDIRREP,
} type_index;
typedef enum {
ASMDIRMEM, // Assembler directive: Insert label location.
ASMDIRREL, // Assembler directive: Insert relative location.
ASMDIRIMM, // Assembler directive: Append immediate.
ASMDIRREP, // Assembler directive: --
//
ADD, OR, ADC, SBB, ADD, OR, ADC, SBB,
AND, SUB, XOR, CMP, AND, SUB, XOR, CMP,
//
INC, DEC, NOT, NEG, INC, DEC, NOT, NEG,
MUL, IMUL, DIV, IDIV, MUL, IMUL, DIV, IDIV,
//
NOP, RETN, RETF, LEAVE, NOP, RETN, RETF, LEAVE,
LOCK, HLT, POPF, PUSHF, LOCK, HLT, POPF, PUSHF,
// WAIT,
SYSENTER, SYSEXIT, SYSCALL, SYSRET, SYSENTER, SYSEXIT, SYSCALL, SYSRET,
PAUSE, CPUID, EMMS, PAUSE, CPUID, EMMS, RSM,
// FNOP, FCHS, FABS, FTST,
FXAM, FLD1, FLDL2T, FLDL2E,
FLDPI, FLDLG2, FLDLN2, FLDZ,
F2XM1, FYL2X, FPTAN, FPATAN,
FXTRACT, FPREM1, FDECSTP, FINCSTP,
FPREM, FYL2XP1, FSQRT, FSINCOS,
FRNDINT, FSCALE, FSIN, FCOS,
ENTER, CALL, IN, OUT, ENTER, CALL, IN, OUT,
//
JMP, JMP,
JO, JNO, JB, JAE, JO, JNO, JB, JAE,
JE, JNE, JBE, JA, JE, JNE, JBE, JA,
JS, JNS, JPE, JPO, JS, JNS, JPE, JPO,
JL, JGE, JLE, JG, JL, JGE, JLE, JG,
//
MOV, MOV,
CMOVO, CMOVNO, CMOVB, CMOVAE, CMOVO, CMOVNO, CMOVB, CMOVAE,
CMOVE, CMOVNE, CMOVBE, CMOVA, CMOVE, CMOVNE, CMOVBE, CMOVA,
CMOVS, CMOVNS, CMOVPE, CMOVPO, CMOVS, CMOVNS, CMOVPE, CMOVPO,
CMOVL, CMOVGE, CMOVLE, CMOVG, CMOVL, CMOVGE, CMOVLE, CMOVG,
//
PUSH, POP, BSWAP, TEST, PUSH, POP, BSWAP, TEST,
RCL, RCR, ROL, ROR, RCL, RCR, ROL, ROR,
SHL, SHR, SAL, SAR, SHL, SHR, SAL, SAR,
@ -54,26 +44,24 @@ typedef enum {
LOOP, LOOPE, LOOPNE, MOVBE, LOOP, LOOPE, LOOPNE, MOVBE,
XADD, XCHG, LEA, POPCNT, XADD, XCHG, LEA, POPCNT,
INTI, BSF, BSR, BOUND, INTI, BSF, BSR, BOUND,
FADD, FSUB, FMUL, FDIV, FADD, FMUL, FCOM, FCOMP,
FNOP, FXAM, FABS, FSCALE, FSUB, FSUBR, FDIV, FDIVR
FSIN, FCOS, FSQRT, FCHS, };
FXCH, FREM, FLDPI, FLDZ,
} operation_index;
typedef enum { enum {
R0, R1, R2, R3, R0, R1, R2, R3,
R4, R5, R6, R7, R4, R5, R6, R7,
R8, R9, R10, R11, R8, R9, R10, R11,
R12, R13, R14, R15, R12, R13, R14, R15
} operand_index; };
extern next text_sector_size; extern unsigned int text_entry_point;
extern byte * text_sector_byte; extern unsigned int text_sector_size;
extern unsigned char * text_sector_byte;
extern int was_instruction_array_empty; extern int was_instruction_array_empty;
extern unsigned int text_entry_point;
extern void assemble (next count, next * array); extern void assemble (unsigned int count, unsigned int * array);
#define ASSEMBLER_H #define ASSEMBLER_H
#endif #endif

View File

@ -4,6 +4,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdarg.h> #include <stdarg.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <string.h>
#include "eaxhla.tab.h" #include "eaxhla.tab.h"

View File

@ -1,69 +1,66 @@
#include "assembler.h" #include "assembler.h"
#include "unix.h" #include "unix.h"
uint8_t elf_main_header_byte [ELF_MAIN_HEADER_SIZE] = { #include <string.h>
unsigned char elf_main_header_byte[ELF_MAIN_HEADER_SIZE] = {
0X7F, 0X45, 0X4C, 0X46, 0X02, 0X01, 0X01, 0X03, 0X7F, 0X45, 0X4C, 0X46, 0X02, 0X01, 0X01, 0X03,
0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00,
0X02, 0X00, 0X3E, 0X00, 0X01, 0X00, 0X00, 0X00, 0X02, 0X00, 0X3E, 0X00, 0X01, 0X00, 0X00, 0X00,
0XB0, 0X00, 0X40, 0X00, 0X00, 0X00, 0X00, 0X00, // entry_point 0XB0, 0X00, 0X40, 0X00, 0X00, 0X00, 0X00, 0X00,
0X40, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X40, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00,
0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00,
0X00, 0X00, 0X00, 0X00, 0X40, 0X00, 0X38, 0X00, 0X00, 0X00, 0X00, 0X00, 0X40, 0X00, 0X38, 0X00,
0X02, 0X00, 0X40, 0X00, 0X00, 0X00, 0X00, 0X00, 0X02, 0X00, 0X40, 0X00, 0X00, 0X00, 0X00, 0X00
}; };
uint8_t elf_text_sector_byte [ELF_TEXT_SECTOR_SIZE] = { unsigned char elf_text_sector_byte[ELF_TEXT_SECTOR_SIZE] = {
0X01, 0X00, 0X00, 0X00, 0X05, 0X00, 0X00, 0X00, 0X01, 0X00, 0X00, 0X00, 0X05, 0X00, 0X00, 0X00,
0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00,
0X00, 0X00, 0X40, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X40, 0X00, 0X00, 0X00, 0X00, 0X00,
0X00, 0X00, 0X40, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X40, 0X00, 0X00, 0X00, 0X00, 0X00,
0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, // HDR + TXT 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00,
0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, // HDR + TXT 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00,
0X00, 0X10, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X10, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00
}; };
uint8_t elf_data_sector_byte [ELF_DATA_SECTOR_SIZE] = { unsigned char elf_data_sector_byte[ELF_DATA_SECTOR_SIZE] = {
0X01, 0X00, 0X00, 0X00, 0X06, 0X00, 0X00, 0X00, 0X01, 0X00, 0X00, 0X00, 0X06, 0X00, 0X00, 0X00,
0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, // HDR + TXT 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00,
0X00, 0X10, 0X40, 0X00, 0X00, 0X00, 0X00, 0X00, // +++ ^ 0X00, 0X10, 0X40, 0X00, 0X00, 0X00, 0X00, 0X00,
0X00, 0X10, 0X40, 0X00, 0X00, 0X00, 0X00, 0X00, // +++ ^ 0X00, 0X10, 0X40, 0X00, 0X00, 0X00, 0X00, 0X00,
0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, // DAT 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00,
0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, // DAT 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00,
0X00, 0X10, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X10, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00
}; };
void elf_main_header (uint8_t has_program, void elf_main_header(unsigned char has_program,
uint8_t for_linux, unsigned char for_linux,
uint8_t for_x86_64) { unsigned char for_x86_64) {
// unsigned int enter = text_entry_point + 0x4000b0u;
uint32_t enter = text_entry_point + 0x4000b0u;
elf_main_header_byte [16] = (has_program) ? 0x02 : 0x03; // library elf_main_header_byte[16] = (has_program) ? 0x02 : 0x03;
elf_main_header_byte [ 7] = (for_linux) ? 0x03 : 0x00; // system v elf_main_header_byte[ 7] = (for_linux) ? 0x03 : 0x00;
elf_main_header_byte [18] = (for_x86_64) ? 0x3e : 0x00; elf_main_header_byte[18] = (for_x86_64) ? 0x3e : 0x00;
memcpy (& elf_main_header_byte [24], & enter, sizeof (enter)); memcpy (& elf_main_header_byte[24], & enter, sizeof(enter));
} }
void elf_text_sector (uint64_t text_size, void elf_text_sector(unsigned long text_size, unsigned long data_size) {
uint64_t data_size) { unsigned long text = ELF_HEADER_SIZE + text_size - data_size;
//
uint64_t text = ELF_HEADER_SIZE + text_size - data_size;
memcpy (& elf_text_sector_byte [32], & text, sizeof (text)); memcpy (& elf_text_sector_byte[32], & text, sizeof(text));
memcpy (& elf_text_sector_byte [40], & text, sizeof (text)); memcpy (& elf_text_sector_byte[40], & text, sizeof(text));
} }
void elf_data_sector (uint64_t text_size, void elf_data_sector(unsigned long text_size, unsigned long data_size) {
uint64_t data_size) { unsigned long data = data_size;
// unsigned long core = ELF_HEADER_SIZE + text_size - data_size;
uint64_t data = data_size; unsigned long move = 0x401000 + core;
uint64_t core = ELF_HEADER_SIZE + text_size - data_size;
uint64_t move = 0x401000 + core;
memcpy (& elf_data_sector_byte [ 8], & core, sizeof (core)); memcpy (& elf_data_sector_byte[ 8], & core, sizeof(core));
memcpy (& elf_data_sector_byte [16], & move, sizeof (move)); memcpy (& elf_data_sector_byte[16], & move, sizeof(move));
memcpy (& elf_data_sector_byte [24], & move, sizeof (move)); memcpy (& elf_data_sector_byte[24], & move, sizeof(move));
memcpy (& elf_data_sector_byte [32], & data, sizeof (data)); memcpy (& elf_data_sector_byte[32], & data, sizeof(data));
memcpy (& elf_data_sector_byte [40], & data, sizeof (data)); memcpy (& elf_data_sector_byte[40], & data, sizeof(data));
} }

View File

@ -1,8 +1,5 @@
#ifndef UNIX_H #ifndef UNIX_H
#include <stdint.h>
#include <string.h>
#define ELF_MAIN_HEADER_SIZE (0x40) #define ELF_MAIN_HEADER_SIZE (0x40)
#define ELF_TEXT_SECTOR_SIZE (0x38) #define ELF_TEXT_SECTOR_SIZE (0x38)
#define ELF_DATA_SECTOR_SIZE (0x38) #define ELF_DATA_SECTOR_SIZE (0x38)
@ -11,19 +8,16 @@
+ ELF_TEXT_SECTOR_SIZE \ + ELF_TEXT_SECTOR_SIZE \
+ ELF_DATA_SECTOR_SIZE) + ELF_DATA_SECTOR_SIZE)
extern uint8_t elf_main_header_byte [ELF_MAIN_HEADER_SIZE]; extern unsigned char elf_main_header_byte[ELF_MAIN_HEADER_SIZE];
extern uint8_t elf_text_sector_byte [ELF_TEXT_SECTOR_SIZE]; extern unsigned char elf_text_sector_byte[ELF_TEXT_SECTOR_SIZE];
extern uint8_t elf_data_sector_byte [ELF_DATA_SECTOR_SIZE]; extern unsigned char elf_data_sector_byte[ELF_DATA_SECTOR_SIZE];
extern void elf_main_header (uint8_t has_program, extern void elf_main_header(unsigned char has_program,
uint8_t for_linux, unsigned char for_linux,
uint8_t for_x86_64); unsigned char for_x86_64);
extern void elf_text_sector (uint64_t text_size, extern void elf_text_sector(unsigned long text_size, unsigned long data_size);
uint64_t data_size); extern void elf_data_sector(unsigned long text_size, unsigned long data_size);
extern void elf_data_sector (uint64_t text_size,
uint64_t data_size);
#define UNIX_H #define UNIX_H
#endif #endif