Some weird changes...

This commit is contained in:
xolatile 2024-10-03 10:48:06 -04:00
parent 7b7ba1f3eb
commit 66bfb4559d
3 changed files with 195 additions and 299 deletions

View File

@ -1,8 +1,8 @@
# xiasma
xiasma -- I'm not sure what this is, even tho I wrote it, but it can assemble ugly bytecode into IA32e instructions.
xiasma -- For some reason, I wrote it to be as "branchless" as possible, but there is one loop and some hidden conditionals.
xiasma -- Printing will be removed, I added it because it looked cool, even tho it slows things down by small amount.
xiasma -- I'm not sure what this is, even tho I wrote it, but it can assemble ugly bytecode into IA32e instructions. \
xiasma -- For some reason, I wrote it to be as "branchless" as possible, but there is one loop and some hidden conditionals. \
xiasma -- Printing will be removed, I added it because it looked cool, even tho it slows things down by small amount. \
Here's the idea behind this project: You want to make an assembler or a compiler, but don't want to do machine code by yourself (unlike me),
you want to use some library. LLVM is good but huge, QBE is great but unique, using GAS, NASM, MASM, fasm (best assembler ever) feels like
@ -10,8 +10,8 @@ cheating to you for whatever reason. You don't want your project to depend on bi
linking, 64-bit Intel/AMD CPUs only, tiny and "fast". This isn't the solution, there's no good solution to this... You'll be able to make an
assembler or a compiler, at the cost of depending on 'xiasma' and 'xtandard', but not production ready one, just a toy / hobby one.
Install: `$ sudo sh install.sh`
Example: `$ cd example && sh compile.sh`
Install: `$ sudo sh install.sh` \
Example: `$ cd example && sh compile.sh` \
Disclaimer:
- This library was written mainly for my own projects, but you can repurpose it for your own needs...

View File

@ -2,17 +2,17 @@
#include <xolatile/xyntax.h>
static int array [] = {
operation_memory, 0,
operation_move, operand_size_32, operand_register, 0, operand_immediate, 1,
operation_move, operand_size_32, operand_register, 7, operand_immediate, 1,
operation_move, operand_size_32, operand_register, 6, operand_relative, 1,
operation_move, operand_size_32, operand_register, 2, operand_immediate, 12,
operation_system_call,
operation_move, operand_size_32, operand_register, 0, operand_immediate, 60,
operation_move, operand_size_32, operand_register, 7, operand_immediate, 0,
operation_system_call,
operation_memory, 1,
operation_immediate, operand_size_8, 12,
new_memory, 0,
move, size_32, for_register, 0, for_immediate, 1,
move, size_32, for_register, 7, for_immediate, 1,
move, size_32, for_register, 6, for_relative, 1,
move, size_32, for_register, 2, for_immediate, 12,
system_call,
move, size_32, for_register, 0, for_immediate, 60,
move, size_32, for_register, 7, for_immediate, 0,
system_call,
new_memory, 1,
new_immediate, size_8, 12,
'H', 'e', 'y', 'o', ' ', 'w', 'o', 'r', 'l', 'd', '!', '\n'
};
@ -21,7 +21,7 @@ int main (void) {
int file = -1;
assemble ((int) (sizeof (array) / sizeof (array [0])), array);
assemble ((int) (sizeof (array) / sizeof (* array)), array);
data_sector_size = 12;

460
xiasma.h
View File

@ -3,46 +3,46 @@
#include <xolatile/xtandard.h>
#define double_begin (operation_add)
#define single_begin (operation_increment)
#define static_1_begin (operation_none)
#define static_2_begin (operation_system_call)
#define jump_if_begin (operation_jump_overflow)
#define move_if_begin (operation_move_overflow)
#define set_if_begin (operation_set_overflow)
#define float_begin (operation_float_add)
#define shift_begin (operation_rotate_left)
#define double_begin (add)
#define single_begin (increment)
#define static_1_begin (none)
#define static_2_begin (system_call)
#define jump_if_begin (jump_overflow)
#define move_if_begin (move_overflow)
#define set_if_begin (set_overflow)
#define float_begin (float_add)
#define shift_begin (rotate_left)
#define operation_jump_not_even (operation_jump_odd)
#define operation_jump_not_odd (operation_jump_even)
#define operation_jump_not_below (operation_jump_above_equal)
#define operation_jump_not_below_equal (operation_jump_above)
#define operation_jump_not_above (operation_jump_below_equal)
#define operation_jump_not_above_equal (operation_jump_below)
#define operation_jump_not_lesser (operation_jump_greater_equal)
#define operation_jump_not_lesser_equal (operation_jump_greater)
#define operation_jump_not_greater (operation_jump_lesser_equal)
#define operation_jump_not_greater_equal (operation_jump_lesser)
#define operation_move_not_even (operation_move_odd)
#define operation_move_not_odd (operation_move_even)
#define operation_move_not_below (operation_move_above_equal)
#define operation_move_not_below_equal (operation_move_above)
#define operation_move_not_above (operation_move_below_equal)
#define operation_move_not_above_equal (operation_move_below)
#define operation_move_not_lesser (operation_move_greater_equal)
#define operation_move_not_lesser_equal (operation_move_greater)
#define operation_move_not_greater (operation_move_lesser_equal)
#define operation_move_not_greater_equal (operation_move_lesser)
#define operation_set_not_even (operation_set_odd)
#define operation_set_not_odd (operation_set_even)
#define operation_set_not_below (operation_set_above_equal)
#define operation_set_not_below_equal (operation_set_above)
#define operation_set_not_above (operation_set_below_equal)
#define operation_set_not_above_equal (operation_set_below)
#define operation_set_not_lesser (operation_set_greater_equal)
#define operation_set_not_lesser_equal (operation_set_greater)
#define operation_set_not_greater (operation_set_lesser_equal)
#define operation_set_not_greater_equal (operation_set_lesser)
#define jump_not_even (jump_odd)
#define jump_not_odd (jump_even)
#define jump_not_below (jump_above_equal)
#define jump_not_below_equal (jump_above)
#define jump_not_above (jump_below_equal)
#define jump_not_above_equal (jump_below)
#define jump_not_lesser (jump_greater_equal)
#define jump_not_lesser_equal (jump_greater)
#define jump_not_greater (jump_lesser_equal)
#define jump_not_greater_equal (jump_lesser)
#define move_not_even (move_odd)
#define move_not_odd (move_even)
#define move_not_below (move_above_equal)
#define move_not_below_equal (move_above)
#define move_not_above (move_below_equal)
#define move_not_above_equal (move_below)
#define move_not_lesser (move_greater_equal)
#define move_not_lesser_equal (move_greater)
#define move_not_greater (move_lesser_equal)
#define move_not_greater_equal (move_lesser)
#define set_not_even (set_odd)
#define set_not_odd (set_even)
#define set_not_below (set_above_equal)
#define set_not_below_equal (set_above)
#define set_not_above (set_below_equal)
#define set_not_above_equal (set_below)
#define set_not_lesser (set_greater_equal)
#define set_not_lesser_equal (set_greater)
#define set_not_greater (set_lesser_equal)
#define set_not_greater_equal (set_lesser)
#define elf_main_header_size (0x40)
#define elf_text_sector_size (0x38)
@ -51,91 +51,56 @@
#define elf_header_size (elf_main_header_size + elf_text_sector_size + elf_data_sector_size)
enum {
operand_size_8, operand_size_16, operand_size_32, operand_size_64,
operand_size_limit
size_8, size_16, size_32, size_64
};
enum {
operand_relative, operand_register, operand_memory, operand_immediate,
operand_limit
for_relative, for_register, for_memory, for_immediate
};
enum {
operation_memory, operation_relative, operation_immediate,
operation_add, operation_or, operation_carry_add, operation_carry_subtract,
operation_and, operation_subtract, operation_xor, operation_compare,
operation_increment, operation_decrement, operation_not, operation_negate,
operation_multiply, operation_sign_multiply, operation_divide, operation_sign_divide,
operation_float_add, operation_float_multiply, operation_float_compare, operation_float_compare_pop,
operation_float_subtract, operation_float_unsubtract, operation_float_divide, operation_float_undivide,
operation_carry_rotate_left, operation_carry_rotate_right, operation_rotate_left, operation_rotate_right,
operation_shift_left, operation_shift_right, operation_sign_shift_left, operation_sign_shift_right,
operation_none, operation_near_return, operation_far_return, operation_leave,
operation_pop_flags, operation_push_flags,
operation_system_call, operation_cpu_identification, operation_float_none, operation_float_change_sign,
operation_float_absolute, operation_float_test, operation_float_examine, operation_float_push_1,
operation_float_push_log2_10, operation_float_push_log2_e, operation_float_push_pi, operation_float_push_log10_2,
operation_float_push_ln_2, operation_float_push_0, operation_float_2xm1, operation_float_yl2x,
operation_float_tangent, operation_float_arctangent, operation_float_extract, operation_float_modulus_push_1,
operation_float_decrement, operation_float_increment, operation_float_modulus, operation_float_yl2xp1,
operation_float_square_root, operation_float_sine_cosine, operation_float_random, operation_float_scale,
operation_float_sine, operation_float_cosine,
operation_enter, operation_call, operation_in, operation_out,
operation_jump, operation_move, operation_pop, operation_push,
operation_jump_overflow, operation_jump_not_overflow, operation_jump_below, operation_jump_above_equal,
operation_jump_equal, operation_jump_not_equal, operation_jump_below_equal, operation_jump_above,
operation_jump_sign, operation_jump_not_sign, operation_jump_even, operation_jump_odd,
operation_jump_lesser, operation_jump_greater_equal, operation_jump_lesser_equal, operation_jump_greater,
operation_move_overflow, operation_move_not_overflow, operation_move_below, operation_move_above_equal,
operation_move_equal, operation_move_not_equal, operation_move_below_equal, operation_move_above,
operation_move_sign, operation_move_not_sign, operation_move_even, operation_move_odd,
operation_move_lesser, operation_move_greater_equal, operation_move_lesser_equal, operation_move_greater,
operation_set_overflow, operation_set_not_overflow, operation_set_below, operation_set_above_equal,
operation_set_equal, operation_set_not_equal, operation_set_below_equal, operation_set_above,
operation_set_sign, operation_set_not_sign, operation_set_even, operation_set_odd,
operation_set_lesser, operation_set_greater_equal, operation_set_lesser_equal, operation_set_greater,
operation_byte_swap, operation_test, operation_exchange, operation_load_address,
operation_bit_scan_forward, operation_bit_scan_reverse,
operation_repeat, operation_repeat_equal, operation_repeat_not_equal, operation_repeat_zero,
operation_repeat_not_zero, operation_loop, operation_loop_equal, operation_loop_not_equal,
operation_limit
new_memory, new_relative, new_immediate,
add, or, carry_add, carry_subtract,
and, subtract, xor, compare,
increment, decrement, not, negate,
multiply, sign_multiply, divide, sign_divide,
float_add, float_multiply, float_compare, float_compare_pop,
float_subtract, float_unsubtract, float_divide, float_undivide,
carry_rotate_left, carry_rotate_right, rotate_left, rotate_right,
shift_left, shift_right, sign_shift_left, sign_shift_right,
none, near_return, far_return, leave,
pop_flags, push_flags,
system_call, cpu_identification, float_none, float_change_sign,
float_absolute, float_test, float_examine, float_push_1,
float_push_log2_10, float_push_log2_e, float_push_pi, float_push_log10_2,
float_push_ln_2, float_push_0, float_2xm1, float_yl2x,
float_tangent, float_arctangent, float_extract, float_modulus_push_1,
float_decrement, float_increment, float_modulus, float_yl2xp1,
float_square_root, float_sine_cosine, float_random, float_scale,
float_sine, float_cosine,
enter, call, in, out,
jump, move, pop, push,
jump_overflow, jump_not_overflow, jump_below, jump_above_equal,
jump_equal, jump_not_equal, jump_below_equal, jump_above,
jump_sign, jump_not_sign, jump_even, jump_odd,
jump_lesser, jump_greater_equal, jump_lesser_equal, jump_greater,
move_overflow, move_not_overflow, move_below, move_above_equal,
move_equal, move_not_equal, move_below_equal, move_above,
move_sign, move_not_sign, move_even, move_odd,
move_lesser, move_greater_equal, move_lesser_equal, move_greater,
set_overflow, set_not_overflow, set_below, set_above_equal,
set_equal, set_not_equal, set_below_equal, set_above,
set_sign, set_not_sign, set_even, set_odd,
set_lesser, set_greater_equal, set_lesser_equal, set_greater,
byte_swap, test, exchange, load_address,
bit_scan_forward, bit_scan_reverse,
repeat, repeat_equal, repeat_not_equal, repeat_zero,
repeat_not_zero, loop, loop_equal, loop_not_equal
};
enum {
register_0, register_1, register_2, register_3,
register_4, register_5, register_6, register_7,
register_8, register_9, register_10, register_11,
register_12, register_13, register_14, register_15,
register_limit
};
static const char * size_name [] = {
"d8 ", "d16", "d32", "d64"
};
static const char * type_name [] = {
"rel", "reg", "mem", "imm"
};
static const char * data_name [] = {
"dirmem", "dirrel", "dirimm",
"add", "or", "adc", "sbb", "and", "sub", "xor", "cmp",
"inc", "dec", "not", "neg", "mul", "imul", "div", "idiv",
"fadd", "fmul", "fcom", "fcomp", "fsub", "fsubr", "fdiv", "fdivr",
"rol", "ror", "rcl", "rcr", "sal", "shr", "shl", "sar",
"nop", "retn", "retf", "leave", "popf", "pushf",
"syscall", "cpuid", "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", "mov", "pop", "push",
"jo", "jno", "jb", "jae", "je", "jne", "jbe", "ja",
"js", "jns", "jpe", "jpo", "jl", "jge", "jle", "jg",
"cmovo", "cmovno", "cmovb", "cmovae", "cmove", "cmovne", "cmovbe", "cmova",
"cmovs", "cmovns", "cmovpe", "cmovpo", "cmovl", "cmovge", "cmovle", "cmovg",
"seto", "setno", "setb", "setae", "sete", "setne", "setbe", "seta",
"sets", "setns", "setpe", "setpo", "setl", "setge", "setle", "setg",
"bswap", "bsf", "bsr", "loop", "loope", "loopne"
register_0, register_1, register_2, register_3, register_4, register_5, register_6, register_7,
register_8, register_9, register_10, register_11, register_12, register_13, register_14, register_15
};
static int empty_count = 0;
@ -144,9 +109,6 @@ static int * empty_array = null;
static int * empty_imbue = null;
static int * empty_store = null;
static int nopification = true;
static int spamification = true;
static int text_sector_size = 0;
static int data_sector_size = 0;
@ -199,9 +161,9 @@ static void inset (int when, int data) {
static void inset_immediate (int when, int size, int data) {
inset ((when), (data >> 0) & 0xff);
inset ((when) && (size >= operand_size_16), (data >> 8) & 0xff);
inset ((when) && (size >= operand_size_32), (data >> 16) & 0xff);
inset ((when) && (size >= operand_size_32), (data >> 24) & 0xff);
inset ((when) && (size >= size_16), (data >> 8) & 0xff);
inset ((when) && (size >= size_32), (data >> 16) & 0xff);
inset ((when) && (size >= size_32), (data >> 24) & 0xff);
}
static void inset_memory (int when, int size, int data, int base) {
@ -216,8 +178,6 @@ static void inset_memory (int when, int size, int data, int base) {
static int store_relative (int * array) {
int relative = array [1];
print ("> /3%s/- %i", data_name [array [0]], array [1]);
empty_array [empty_holes] = text_sector_size;
empty_imbue [empty_holes] = relative;
@ -230,8 +190,6 @@ static int store_memory (int * array) {
int operation = array [0],
memory = array [1];
print ("> /3%s/- %i", data_name [operation], memory);
empty_store [memory] = text_sector_size;
++empty_count;
@ -245,8 +203,6 @@ static int store_immediate (int * array) {
size = array [1],
amount = array [2];
print ("> /3%s/- /4%s/- %i", data_name [operation], size_name [size], amount);
for (index = 0; index < amount; ++index) {
inset_immediate (true, size, array [3 + index]);
}
@ -255,27 +211,27 @@ static int store_immediate (int * array) {
}
static void short_prefix (int size) {
inset (size == operand_size_16, 0x66);
inset (size == size_16, 0x66);
}
static void long_prefix (int size, int to, int destination, int from, int source) {
int to_upper = (to == operand_register) && (upper (destination)),
from_upper = (from == operand_register) && (upper (source)),
extension = (size == operand_size_64);
int to_upper = (to == for_register) && (upper (destination)),
from_upper = (from == for_register) && (upper (source)),
extension = (size == size_64);
inset (extension || to_upper || from_upper, 0x40 + 0x01 * to_upper + 0x04 * from_upper + 0x08 * extension);
}
static void modify_registers (int to, int destination, int from, int source) {
int to_register_from_register = ((to == operand_register) && (from == operand_register));
int to_register_from_register = ((to == for_register) && (from == for_register));
inset (to_register_from_register, 0xc0 + 0x01 * (destination & 0x07) + 0x08 * (source & 0x07));
}
static void modify_memory (int operation, int to, int from) {
int to_register_from_memory = ((to == operand_register) && (from == operand_memory)),
to_memory_from_register = ((to == operand_memory) && (from == operand_register)),
to_memory_from_immediate = ((to == operand_memory) && (from == operand_immediate));
int to_register_from_memory = ((to == for_register) && (from == for_memory)),
to_memory_from_register = ((to == for_memory) && (from == for_register)),
to_memory_from_immediate = ((to == for_memory) && (from == for_immediate));
inset (to_register_from_memory || to_memory_from_register, 0x05 + 0x08 * operation * to_memory_from_immediate);
}
@ -288,20 +244,18 @@ static int build_double (int * array) {
from = array [4],
source = array [5];
int to_register_from_register = ((to == operand_register) && (from == operand_register)),
to_register_from_memory = ((to == operand_register) && (from == operand_memory)),
to_register_from_immediate = ((to == operand_register) && (from == operand_immediate)),
to_register_from_relative = ((to == operand_register) && (from == operand_relative)),
to_memory_from_register = ((to == operand_memory) && (from == operand_register)),
to_memory_from_immediate = ((to == operand_memory) && (from == operand_immediate));
print ("> /3%s/- /4%s/- /6%s/- %i /6%s/- %i", data_name [operation], size_name [size], type_name [to], destination, type_name [from], source);
int to_register_from_register = ((to == for_register) && (from == for_register)),
to_register_from_memory = ((to == for_register) && (from == for_memory)),
to_register_from_immediate = ((to == for_register) && (from == for_immediate)),
to_register_from_relative = ((to == for_register) && (from == for_relative)),
to_memory_from_register = ((to == for_memory) && (from == for_register)),
to_memory_from_immediate = ((to == for_memory) && (from == for_immediate));
short_prefix (size);
long_prefix (size, to, destination, from, source);
inset (to_register_from_immediate, 0x80 + 0x01 * (size != operand_size_8));
inset (to_register_from_immediate, 0x80 + 0x01 * (size != size_8));
inset (to_register_from_immediate, 0xc0 + 0x08 * (operation - double_begin) + 0x01 * (destination & 0x07));
modify_registers (to, destination, from, source);
@ -309,10 +263,10 @@ static int build_double (int * array) {
modify_memory (destination, to, from);
modify_memory (source, to, from);
inset_memory (to_register_from_memory, operand_size_32, source, 0x1000 - text_sector_size - 4);
inset_memory (to_memory_from_register, operand_size_32, destination, 0x1000 - text_sector_size - 4);
inset_memory (to_memory_from_immediate, operand_size_32, destination, 0x1000 - text_sector_size - 4);
inset_memory (to_register_from_relative, operand_size_32, source, 0x4010b0 - text_sector_size - 4);
inset_memory (to_register_from_memory, size_32, source, 0x1000 - text_sector_size - 4);
inset_memory (to_memory_from_register, size_32, destination, 0x1000 - text_sector_size - 4);
inset_memory (to_memory_from_immediate, size_32, destination, 0x1000 - text_sector_size - 4);
inset_memory (to_register_from_relative, size_32, source, 0x4010b0 - text_sector_size - 4);
inset_immediate (to_register_from_immediate, size, source);
inset_immediate (to_memory_from_immediate, size, source);
@ -326,22 +280,20 @@ static int build_single (int * array) {
to = array [2],
destination = array [3];
int irregularity = ((operation == operation_increment) || (operation == operation_decrement));
print ("> /3%s/- /4%s/- /6%s/- %i", data_name [operation], size_name [size], type_name [to], destination);
int irregularity = ((operation == increment) || (operation == decrement));
short_prefix (size);
long_prefix (size, to, destination, 0, 0);
inset ((size == operand_size_8) && (to == operand_register) && front (destination), 0x40);
inset ((size == size_8) && (to == for_register) && front (destination), 0x40);
inset (true, 0xf7 + 0x08 * irregularity - 0x01 * (size == operand_size_8));
inset (true, 0xf7 + 0x08 * irregularity - 0x01 * (size == size_8));
inset (to == operand_register, 0xc0 + 0x08 * (operation - single_begin) + 0x01 * (destination & 0x07));
inset (to == operand_memory, 0x05 + 0x08 * (operation - single_begin));
inset (to == for_register, 0xc0 + 0x08 * (operation - single_begin) + 0x01 * (destination & 0x07));
inset (to == for_memory, 0x05 + 0x08 * (operation - single_begin));
inset_memory (to == operand_memory, operand_size_32, destination, 0x1000 - (text_sector_size + 4));
inset_memory (to == for_memory, size_32, destination, 0x1000 - (text_sector_size + 4));
return (3);
}
@ -353,8 +305,6 @@ static int build_static_1 (int * array) {
0x90, 0xc3, 0xcb, 0xc9, 0x9d, 0x9c
};
print ("> /3%s/-", data_name [operation]);
inset (true, data [operation - static_1_begin]);
return (0);
@ -370,9 +320,7 @@ static int build_static_2 (int * array) {
0xfad9, 0xfbd9, 0xfcd9, 0xfdd9, 0xfed9, 0xffd9
};
print ("> /3%s/-", data_name [operation]);
inset_immediate (true, operand_size_16, data [operation - static_2_begin]);
inset_immediate (true, size_16, data [operation - static_2_begin]);
return (0);
}
@ -382,14 +330,12 @@ static int build_jump_if (int * array) {
size = array [1],
location = array [3];
print ("> /3%s/- /4%s/- /1rel/- %i", data_name [operation], size_name [size], location);
inset (far (location) && (size == operand_size_32), 0x0f);
inset (far (location) && (size == size_32), 0x0f);
inset (far (location), 0x80 + operation - jump_if_begin);
inset (near (location), 0x70 + operation - jump_if_begin);
inset_memory (true, operand_size_32, location, -(text_sector_size + 4));
inset_memory (true, size_32, location, -(text_sector_size + 4));
return (3);
}
@ -402,8 +348,6 @@ static int build_move_if (int * array) {
from = array [4],
source = array [5];
print ("> /3%s/- /4%s/- /6%s/- %i /6%s/- %i", data_name [operation], size_name [size], type_name [to], destination, type_name [from], source);
short_prefix (size);
long_prefix (size, to, destination, from, source);
@ -423,18 +367,16 @@ static int build_set_if (int * array) {
to = array [2],
destination = array [3];
print ("> /3%s/- /1d8 /- /6%s/- %i", data_name [operation], type_name [to], destination);
inset ((to == operand_register) && (front (destination)), 0x40);
inset ((to == operand_register) && (upper (destination)), 0x41);
inset ((to == for_register) && (front (destination)), 0x40);
inset ((to == for_register) && (upper (destination)), 0x41);
inset (true, 0x0f);
inset (true, 0x90 + operation - set_if_begin);
inset (to == operand_register, 0xc0 + 0x01 * (destination & 0x07));
inset (to == operand_memory, 0x05);
inset (to == for_register, 0xc0 + 0x01 * (destination & 0x07));
inset (to == for_memory, 0x05);
inset_memory (to == operand_memory, operand_size_32, destination, 0x1000 - (text_sector_size + 4));
inset_memory (to == for_memory, size_32, destination, 0x1000 - (text_sector_size + 4));
return (3);
}
@ -445,18 +387,16 @@ static int build_jump (int * array) {
to = array [2],
destination = array [3];
print ("> /3%s/- /4%s/- /6%s/- %i", data_name [operation], size_name [size], type_name [to], destination);
inset ((to == for_register) && upper (destination), 0X41);
inset ((to == operand_register) && upper (destination), 0X41);
inset (to == for_relative, 0xe9 + 0x02 * (size == size_8));
inset (to == for_register, 0xff);
inset (to == for_register, 0xe0 + 0x01 * (destination & 0x07));
inset (to == for_memory, 0xff);
inset (to == for_memory, 0x25);
inset (to == operand_relative, 0xe9 + 0x02 * (size == operand_size_8));
inset (to == operand_register, 0xff);
inset (to == operand_register, 0xe0 + 0x01 * (destination & 0x07));
inset (to == operand_memory, 0xff);
inset (to == operand_memory, 0x25);
inset_memory (to == operand_relative, operand_size_32, destination, -(text_sector_size + 4));
inset_memory (to == operand_memory, operand_size_32, destination, 0x4010b0);
inset_memory (to == for_relative, size_32, destination, -(text_sector_size + 4));
inset_memory (to == for_memory, size_32, destination, 0x4010b0);
return (3);
}
@ -470,39 +410,36 @@ static int build_move (int * array) {
source = array [5],
extension = array [6];
print ("> /3%s/- /4%s/- /6%s/- %i /6%s/- %i %i", data_name [operation], size_name [size], type_name [to], destination, type_name [from],
source, (size == operand_size_64) ? extension : 0);
short_prefix (size);
long_prefix (size, to, destination, from, source);
inset ((to == operand_register) && (from == operand_register), 0x88 + 0x01 * (size != operand_size_8));
inset ((to == operand_register) && (from == operand_memory), 0x8a + 0x01 * (size != operand_size_8));
inset ((to == operand_memory) && (from == operand_register), 0x88 + 0x01 * (size != operand_size_8));
inset ((to == for_register) && (from == for_register), 0x88 + 0x01 * (size != size_8));
inset ((to == for_register) && (from == for_memory), 0x8a + 0x01 * (size != size_8));
inset ((to == for_memory) && (from == for_register), 0x88 + 0x01 * (size != size_8));
modify_memory (destination, to, from);
modify_memory (source, to, from);
modify_registers (to, destination, from, source);
inset ((to == operand_register) && ((from == operand_immediate) || (from == operand_relative)), 0xb0 + 0x08 * (size != operand_size_8) + 0x01 * (destination & 0x07));
inset ((to == for_register) && ((from == for_immediate) || (from == for_relative)), 0xb0 + 0x08 * (size != size_8) + 0x01 * (destination & 0x07));
inset ((to == operand_memory) && (from == operand_immediate), 0xc6 + 0x01 * (size != operand_size_8));
inset ((to == operand_memory) && (from == operand_immediate), 0x05);
inset ((to == for_memory) && (from == for_immediate), 0xc6 + 0x01 * (size != size_8));
inset ((to == for_memory) && (from == for_immediate), 0x05);
inset_memory ((to == operand_register) && (from == operand_memory), operand_size_32, source, 0x1000 - text_sector_size - 4);
inset_memory ((to == operand_memory) && (from == operand_register), operand_size_32, destination, 0x1000 - text_sector_size - 4);
inset_memory ((to == operand_memory) && (from == operand_immediate), operand_size_32, destination, 0x1000 - text_sector_size - 4);
inset_memory ((to == operand_register) && (from == operand_relative), operand_size_32, source, 0x4010b0);
inset_memory ((to == for_register) && (from == for_memory), size_32, source, 0x1000 - text_sector_size - 4);
inset_memory ((to == for_memory) && (from == for_register), size_32, destination, 0x1000 - text_sector_size - 4);
inset_memory ((to == for_memory) && (from == for_immediate), size_32, destination, 0x1000 - text_sector_size - 4);
inset_memory ((to == for_register) && (from == for_relative), size_32, source, 0x4010b0);
inset_immediate ((to == operand_register) && (from == operand_immediate) && (size != operand_size_64), size, source);
inset_immediate ((to == operand_memory) && (from == operand_immediate) && (size != operand_size_64), size, source);
inset_immediate ((to == operand_register) && (from == operand_immediate) && (size == operand_size_64), operand_size_32, source);
inset_immediate ((to == operand_register) && (from == operand_immediate) && (size == operand_size_64), operand_size_32, extension);
inset_immediate ((to == operand_register) && (from == operand_immediate) && (size == operand_size_64), operand_size_32, 0);
inset_immediate ((to == for_register) && (from == for_immediate) && (size != size_64), size, source);
inset_immediate ((to == for_memory) && (from == for_immediate) && (size != size_64), size, source);
inset_immediate ((to == for_register) && (from == for_immediate) && (size == size_64), size_32, source);
inset_immediate ((to == for_register) && (from == for_immediate) && (size == size_64), size_32, extension);
inset_immediate ((to == for_register) && (from == for_immediate) && (size == size_64), size_32, 0);
return (5 + (size == operand_size_64));
return (5 + (size == size_64));
}
static int build_call (int * array) {
@ -510,16 +447,14 @@ static int build_call (int * array) {
from = array [1],
source = array [2];
print ("> /3%s/- /6%s/- %i", data_name [operation], type_name [from], source);
inset ((from == for_register) && (upper (source)), 0x41);
inset ((from == operand_register) && (upper (source)), 0x41);
inset (from == for_relative, 0xe8);
inset (from == for_register, 0xff);
inset (from == operand_relative, 0xe8);
inset (from == operand_register, 0xff);
inset_memory (from == for_relative, size_32, source, -(text_sector_size + 4));
inset_memory (from == operand_relative, operand_size_32, source, -(text_sector_size + 4));
inset (from == operand_register, (0xd0 + 0x01 * (source & 0x07)));
inset (from == for_register, (0xd0 + 0x01 * (source & 0x07)));
return (2);
}
@ -529,12 +464,10 @@ static int build_enter (int * array) {
dynamic_storage = array [1],
nesting_level = array [2];
print ("> /3%s/- %i %i", data_name [operation], dynamic_storage, nesting_level);
inset (true, 0xc8);
inset_immediate (true, operand_size_16, dynamic_storage);
inset_immediate (true, operand_size_8, nesting_level & 0x1f);
inset_immediate (true, size_16, dynamic_storage);
inset_immediate (true, size_8, nesting_level & 0x1f);
return (2);
}
@ -545,13 +478,11 @@ static int build_float (int * array) {
from = array [2],
source = array [3];
print ("> /3%s/- /4%s/- /6%s/- %i", data_name [operation], size_name [size], type_name [from], source);
inset (from == operand_memory, 0xd8 + 0x04 * (size == operand_size_64));
inset (from == for_memory, 0xd8 + 0x04 * (size == size_64));
modify_memory (operation, 0, from);
inset_memory (from == operand_memory, size, source, 0);
inset_memory (from == for_memory, size, source, 0);
return (3);
}
@ -563,19 +494,17 @@ static int build_shift (int * array) {
destination = array [3],
offset = array [5];
print ("> /3%s/- /4%s/- /6%s/- %i /1imm/- %i", data_name [operation], size_name [size], type_name [to], destination, offset);
short_prefix (size);
long_prefix (size, to, destination, 0, 0);
inset (true, 0xc0 + 0x01 * (size != operand_size_8));
inset (true, 0xc0 + 0x01 * (size != size_8));
inset (to == operand_register, 0x05 + 0x08 * (operation & 7));
inset (to == operand_memory, 0xc0 + 0x08 * (operation & 7));
inset (to == for_register, 0x05 + 0x08 * (operation & 7));
inset (to == for_memory, 0xc0 + 0x08 * (operation & 7));
inset_memory (to == operand_memory, operand_size_32, destination, 0x1000 - text_sector_size - 4);
inset_immediate (true, operand_size_8, offset);
inset_memory (to == for_memory, size_32, destination, 0x1000 - text_sector_size - 4);
inset_immediate (true, size_8, offset);
return (5);
}
@ -586,13 +515,11 @@ static int build_in_out (int * array) {
type = array [2],
port = array [3];
print ("> /3%s/- /4%s/- /6%s/- %i", data_name [move], size_name [size], type_name [type], port);
short_prefix (size);
inset (true, 0xe4 + 0x01 * (size != operand_size_8) + 0x02 * (move != operation_out) + 0x08 * (type == operand_register));
inset (true, 0xe4 + 0x01 * (size != size_8) + 0x02 * (move != out) + 0x08 * (type == for_register));
inset_immediate (type == operand_immediate, operand_size_8, port);
inset_immediate (type == for_immediate, size_8, port);
return (3);
}
@ -603,17 +530,15 @@ static int build_pop (int * array) {
to = array [2],
destination = array [3];
print ("> /3%s/- /4%s/- /6%s/- %i", data_name [operation], size_name [size], type_name [to], destination);
short_prefix (size);
inset ((to == operand_register) && (upper (destination)), 0x41);
inset ((to == for_register) && (upper (destination)), 0x41);
inset (to == operand_register, 0x58 + 0x01 * (destination & 0x07));
inset (to == operand_memory, 0x8f);
inset (to == operand_memory, 0x05);
inset (to == for_register, 0x58 + 0x01 * (destination & 0x07));
inset (to == for_memory, 0x8f);
inset (to == for_memory, 0x05);
inset_memory (to == operand_memory, operand_size_32, destination, 0);
inset_memory (to == for_memory, size_32, destination, 0);
return (3);
}
@ -624,19 +549,17 @@ static int build_push (int * array) {
from = array [2],
source = array [3];
print ("> /3%s/- /4%s/- /6%s/- %i", data_name [operation], size_name [size], type_name [from], source);
short_prefix (size);
inset ((from == operand_register) && (upper (source)), 0x41);
inset ((from == for_register) && (upper (source)), 0x41);
inset (from == operand_register, 0x50 + 0x01 * (source & 0x07));
inset (from == operand_memory, 0xff);
inset (from == operand_memory, 0x35);
inset (from == operand_immediate, 0x68 + 0x02 * (size == operand_size_8));
inset (from == for_register, 0x50 + 0x01 * (source & 0x07));
inset (from == for_memory, 0xff);
inset (from == for_memory, 0x35);
inset (from == for_immediate, 0x68 + 0x02 * (size == size_8));
inset_memory (from == operand_memory, operand_size_32, source, 0);
inset_immediate (from == operand_immediate, size, source);
inset_memory (from == for_memory, size_32, source, 0);
inset_immediate (from == for_immediate, size, source);
return (3);
}
@ -646,9 +569,7 @@ static int build_swap (int * array) {
size = array [1],
destination = array [3];
print ("> /3%s/- /4%s/- /1reg/- %i", data_name [operation], size_name [size], destination);
long_prefix (size, operand_register, destination, 0, 0);
long_prefix (size, for_register, destination, 0, 0);
inset (true, 0x0f);
inset (true, 0xc8 + 0x01 * (destination & 0x07));
@ -663,19 +584,17 @@ static int build_bit_scan (int * array) {
from = array [4],
source = array [5];
print ("> /3%s/- /4%s/- /1reg/- %i /6%s/- %i", data_name [operation], size_name [size], destination, type_name [from], source);
short_prefix (size);
long_prefix (size, operand_register, destination, from, source);
long_prefix (size, for_register, destination, from, source);
inset_immediate (true, operand_size_16, 0xbc0f);
inset_immediate (true, size_16, 0xbc0f);
modify_registers (operand_register, destination, from, source);
modify_registers (for_register, destination, from, source);
inset (from == operand_memory, 0x05 + 0x08 * destination);
inset (from == for_memory, 0x05 + 0x08 * destination);
inset_memory (from == operand_memory, operand_size_32, source, 0x1000 - (text_sector_size + 4));
inset_memory (from == for_memory, size_32, source, 0x1000 - (text_sector_size + 4));
return (5);
}
@ -684,13 +603,11 @@ static int build_loop (int * array) {
int operation = array [0],
location = array [3];
print ("> /3%s/- /1d8 rel/- %i", data_name [operation], location);
inset (operation == loop_not_equal, 0xe0);
inset (operation == loop_equal, 0xe1);
inset (operation == loop, 0xe2);
inset (operation == operation_loop_not_equal, 0xe0);
inset (operation == operation_loop_equal, 0xe1);
inset (operation == operation_loop, 0xe2);
inset_memory (1, operand_size_8, location, -(text_sector_size + 1));
inset_memory (1, size_8, location, -(text_sector_size + 1));
return (3);
}
@ -748,29 +665,8 @@ static int (* build_instruction []) (int * array) = {
static int assemble (int count, int * array) {
int index;
text_sector_byte = allocate (4096 * (int) sizeof (* text_sector_byte));
empty_array = allocate (1024 * (int) sizeof (* empty_array));
empty_imbue = allocate (1024 * (int) sizeof (* empty_imbue));
empty_store = allocate (1024 * (int) sizeof (* empty_store));
for (index = 0; index < count; ++index) {
int check_at;
int byte;
inset ((nopification == true) && (array [index] > operation_immediate), 0x90);
check_at = text_sector_size;
index += build_instruction [array [index]] (& array [index]);
print (" -- /5");
for (byte = check_at; byte < text_sector_size; ++byte) {
echo_byte (text_sector_byte [byte]);
}
print ("/-\n");
}
for (index = 1; index < empty_holes; ++index) {