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

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

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

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

@ -1,69 +1,66 @@
#include "assembler.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,
0X00, 0X00, 0X00, 0X00, 0X00, 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,
0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 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,
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, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, // HDR + TXT
0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, // HDR + TXT
0X00, 0X10, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00,
0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00,
0X00, 0X00, 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,
0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, // HDR + TXT
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, // DAT
0X00, 0X10, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00,
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, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00,
0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00,
0X00, 0X10, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00
};
void elf_main_header (uint8_t has_program,
uint8_t for_linux,
uint8_t for_x86_64) {
//
uint32_t enter = text_entry_point + 0x4000b0u;
void elf_main_header(unsigned char has_program,
unsigned char for_linux,
unsigned char for_x86_64) {
unsigned int enter = text_entry_point + 0x4000b0u;
elf_main_header_byte [16] = (has_program) ? 0x02 : 0x03; // library
elf_main_header_byte [ 7] = (for_linux) ? 0x03 : 0x00; // system v
elf_main_header_byte [18] = (for_x86_64) ? 0x3e : 0x00;
elf_main_header_byte[16] = (has_program) ? 0x02 : 0x03;
elf_main_header_byte[ 7] = (for_linux) ? 0x03 : 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,
uint64_t data_size) {
//
uint64_t text = ELF_HEADER_SIZE + text_size - data_size;
void elf_text_sector(unsigned long text_size, unsigned long data_size) {
unsigned long text = ELF_HEADER_SIZE + text_size - data_size;
memcpy (& elf_text_sector_byte [32], & text, sizeof (text));
memcpy (& elf_text_sector_byte [40], & text, sizeof (text));
memcpy (& elf_text_sector_byte[32], & text, sizeof(text));
memcpy (& elf_text_sector_byte[40], & text, sizeof(text));
}
void elf_data_sector (uint64_t text_size,
uint64_t data_size) {
//
uint64_t data = data_size;
uint64_t core = ELF_HEADER_SIZE + text_size - data_size;
uint64_t move = 0x401000 + core;
void elf_data_sector(unsigned long text_size, unsigned long data_size) {
unsigned long data = data_size;
unsigned long core = ELF_HEADER_SIZE + text_size - data_size;
unsigned long move = 0x401000 + core;
memcpy (& elf_data_sector_byte [ 8], & core, sizeof (core));
memcpy (& elf_data_sector_byte [16], & 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 [40], & data, sizeof (data));
memcpy (& elf_data_sector_byte[ 8], & core, sizeof(core));
memcpy (& elf_data_sector_byte[16], & 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[40], & data, sizeof(data));
}

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