From 113bafb7d577affa8c1865718ea6b6b2f4d339bb Mon Sep 17 00:00:00 2001 From: xolatile Date: Fri, 5 Jul 2024 17:01:10 -0400 Subject: [PATCH] Work in progress on jump and move... --- documentation/test.asm | 73 ++++++++++++++++++++++++++- source/assembler.c | 110 ++++++++++++++++++++++++++++++++++++++--- source/assembler.h | 23 ++++++--- 3 files changed, 191 insertions(+), 15 deletions(-) diff --git a/documentation/test.asm b/documentation/test.asm index 7bbd8e0..84d227b 100644 --- a/documentation/test.asm +++ b/documentation/test.asm @@ -12,7 +12,7 @@ entry $ ; 66 41 81 C1 FF 7F | add r9w 07fffh ; 66 81 05 00 11 00 00 FF 7F | add [x] 07fffh - nop +fff: nop add r9w, [x2] nop add [x2], r9w @@ -354,11 +354,82 @@ entry $ ;~idiv cx nop + nop + nop + +nnn: nop + jmp nnn + nop + jmp fff + nop + jmp rax + nop + jmp rcx + nop + jmp r8 + nop + jmp r9 + nop + jmp word[x2] + nop + jmp qword[x8] nop nop nop + nop + jo nnn + nop + jno fff + nop + jb fff + nop + jae fff + nop + je fff + nop + jne fff + nop + jbe fff + nop + ja fff + nop + js fff + nop + jns fff + nop + jpe fff + nop + jpo fff + nop + jl fff + nop + jge fff + nop + jle fff + nop + jg fff + + nop + nop + nop + + nop + cmovo cx, r9w + nop + cmovg cx, r9w + nop + cmovo ecx, r9d + nop + cmovg ecx, r9d + nop + cmovo rcx, r9 + nop + cmovg rcx, r9 + + nop + nop nop nop diff --git a/source/assembler.c b/source/assembler.c index e634a3e..ea9bcdf 100644 --- a/source/assembler.c +++ b/source/assembler.c @@ -27,14 +27,28 @@ splint assembler.h: #define SPECIAL_1_END (HLT) #define SPECIAL_2_BEGIN (SYSENTER) #define SPECIAL_2_END (CPUID) +#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) #define IRREGULAR_COUNT (IRREGULAR_END - IRREGULAR_BEGIN + 1) #define SPECIAL_1_COUNT (SPECIAL_1_END - SPECIAL_1_BEGIN + 1) #define SPECIAL_2_COUNT (SPECIAL_2_END - SPECIAL_2_BEGIN + 1) +#define JUMP_IF_COUNT (JUMP_IF_END - JUMP_IF_BEGIN + 1) +#define MOVE_IF_COUNT (MOVE_IF_END - MOVE_IF_BEGIN + 1) +// Regulates displacement, immediate, label, variable, constant, string data. +static next * empty_from; +static next * empty_to; +static next * imbue_with; +static next * imbue_size; + +// Main function. static void place (form when, byte data) { + /**/ token_array [token_count] = data; token_count += (next) when; @@ -44,13 +58,43 @@ static form valid (form data) { return ((data >= 0) && (data <= 15)); } static form lower (form data) { return ((data >= 0) && (data <= 7)); } static form upper (form data) { return ((data >= 8) && (data <= 15)); } +// Important stuff that I need to handle later, it saves bytes! +static form far (next label) { return (1); /* DO NOT CHANGE YET! */ } +static form near (next label) { return (0); /* DO NOT CHANGE YET! */ } + +// -- +static void displacement (form size, + next data) { + /**/ + (void) size; + + place (1, (data >> 24) & 0XFF); + place (1, (data >> 16) & 0XFF); + place (1, (data >> 8) & 0XFF); + place (1, (data >> 0) & 0XFF); +} + +// -- +static void immediate (form size, + next data) { + /**/ + (void) size; + + place (1, (data >> 24) & 0XFF); + place (1, (data >> 16) & 0XFF); + place (1, (data >> 8) & 0XFF); + place (1, (data >> 0) & 0XFF); +} + static void build_short_prefix (form when) { place (when, 0X66); } +// 40-4D!0X02 static void build_long_prefix (form use_big_registers, form use_new_destination, form use_new_source) { + /**/ place (use_big_registers || use_new_destination || use_new_source, (byte) (0X40 + 0X01 * use_new_destination @@ -58,32 +102,40 @@ static void build_long_prefix (form use_big_registers, + 0X08 * use_big_registers)); } +// C0-FF static void build_register_direction (form when, next destination, next source) { + /**/ place (when, (byte) (0XC0 - + 0X01 * (destination % 8) - + 0X08 * (source % 8))); + + 0X01 * (destination & 0X07) + + 0X08 * (source & 0X07))); } +// 05-3D static void build_register_redirection (form when, next direction) { + /**/ place (when, (byte) (0X05 - + 0X08 * (direction % 8))); + + 0X08 * (direction & 0X07))); } +// 80/81 static void build_constant (form when, size_index size) { + /**/ place (when, (byte) (0X80 + 0X01 * (size != D8))); } +// REGULAR_BEGIN-REGULAR_END D8-D64 REG/MEM R0-R15/MEM -||-/IMM -||-/IMM static void build_regular (operation_index operation, size_index size, type_index to, next destination, type_index from, next source) { + /**/ build_short_prefix (size == D16); build_long_prefix (size == D64, @@ -93,7 +145,7 @@ static void build_regular (operation_index operation, build_constant (from == IMM, size); place (1, (byte) (0X08 * (operation - REGULAR_BEGIN) - + destination % 8 * ((to == REG) && (from == IMM)) + + (destination & 0X07) * ((to == REG) && (from == IMM)) + 0X01 * (size != D8) + 0X02 * ((from == MEM) && (to == REG)) + 0X04 * ((from == IMM) && (to == MEM)) @@ -106,27 +158,30 @@ static void build_regular (operation_index operation, build_register_redirection ((to == MEM) && (from == REG), source); } +// IRREGULAR_BEGIN-IRREGULAR_END D8-D64 REG/MEM R0-R15/MEM static void build_irregular (operation_index operation, size_index size, type_index to, next destination) { + /**/ build_short_prefix (size == D16); build_long_prefix (size == D64, - (to == REG) && (upper (destination)), 0); + (to == REG) && (upper (destination)), 0); place (1, (byte) (0XF6 + 0X08 * ((operation == INC) || (operation == DEC)) - + 0X01 * (size != D8))); + + 0X01 * (size != D8))); place (to == REG, (byte) (0XC0 + 0X08 * (operation - IRREGULAR_BEGIN)) - + 0X01 * (destination % 8)); + + 0X01 * (destination & 0X07)); place (to == MEM, (byte) (0X05 + 0X08 * (operation - IRREGULAR_BEGIN))); } +// SPECIAL_1_BEGIN-SPECIAL_1_END static void build_special_1 (operation_index operation) { const byte data [1 * SPECIAL_1_COUNT] = { 0X90, 0XC3, 0XCB, 0XC9, 0XF0, 0XF4 @@ -135,6 +190,7 @@ static void build_special_1 (operation_index operation) { place (1, data [operation - SPECIAL_1_BEGIN]); } +// SPECIAL_2_BEGIN-SPECIAL_2_END static void build_special_2 (operation_index operation) { const byte data [2 * SPECIAL_2_COUNT] = { 0X0F, 0X0F, 0X0F, 0X0F, 0XF3, 0X0F, @@ -145,10 +201,48 @@ static void build_special_2 (operation_index operation) { place (1, data [operation - SPECIAL_2_BEGIN + SPECIAL_2_COUNT]); } +// JUMP_IF_BEGIN-JUMP_IF_END D8/32 IMM8/32 +static void build_jump_if (operation_index operation, + size_index size, + next destination) { + /**/ + (void) size; /* HIGHLY DEPENDS FOR FAR AND NEAR JUMPS! */ + + place (far (destination), 0X0F); /* EVERYTHING IS FAR JUMP! */ + place (far (destination), (byte) (0X80 + operation - JUMP_IF_BEGIN)); + place (near (destination), (byte) (0X70 + operation - JUMP_IF_BEGIN)); + + //~displacement (4, 0X12345678); +} + +// MOVE_IF_BEGIN-MOVE_IF_END D16-D64 REG R0-R15 -||-/MEM -||-/MEM +static void build_move_if (operation_index operation, + size_index size, + type_index to, + next destination) { + /**/ + build_short_prefix (size == D16); + + build_long_prefix (size == D64, + (to == REG) && (upper (destination)), 0); + + place (1, 0X0F); + place (1, (byte) (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! +} + next token_count; byte * token_array; -void assemble (next count, next * array) { +void assemble (next count, + next * array) { + /**/ next index; for (index = 0; index < count; ++index) { diff --git a/source/assembler.h b/source/assembler.h index 43bad47..a26cdf1 100644 --- a/source/assembler.h +++ b/source/assembler.h @@ -15,19 +15,30 @@ typedef enum { typedef enum { ADD, OR, ADC, SBB, AND, SUB, XOR, CMP, + /**/ INC, DEC, NOT, NEG, UMUL, IMUL, UDIV, IDIV, + /**/ NOP, RETN, RETF, LEAVE, LOCK, HLT, + /**/ SYSENTER, SYSEXIT, SYSCALL, SYSRET, PAUSE, CPUID, + /**/ ENTER, CALL, IN, OUT, - JMP, JPE, JS, JPO, - JE, JNE, JZ, JNZ, - JA, JNA, JB, JNB, - MOV, CMOVPE, CMOVS, CMOVPO, - CMOVE, CMOVNE, CMOVZ, CMOVNZ, - CMOVA, CMOVNA, CMOVB, CMOVNB, + /**/ + 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,