Merge branch 'master' of https://codeberg.org/eaxcc/eaxcc
This commit is contained in:
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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"
|
||||||
|
|
||||||
|
@ -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));
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
Reference in New Issue
Block a user