This commit is contained in:
anon
2024-07-04 18:13:56 +02:00
4 changed files with 237 additions and 205 deletions

View File

@ -5,38 +5,22 @@
#include "../source/assembler.c"
int main (void) {
token_array = malloc (144UL * sizeof (* token_array));
unsigned int index;
assemble (OPERATION_ADD_F, SIZE_64B,
TYPE_REGISTER, OPERAND_REGISTER_1,
TYPE_REGISTER, OPERAND_REGISTER_2);
output_array = malloc (144UL * sizeof (* output_array));
assemble (OPERATION_ADD_F, SIZE_32B,
TYPE_REGISTER, OPERAND_REGISTER_1,
TYPE_VARIABLE, 12);
build_regular (ADC, D64, REG, R1, REG, R2);
build_regular (ADC, D32, REG, R1, MEM, 12);
build_regular (ADC, D16, MEM, 12, REG, R10);
build_regular (ADC, D8, REG, R3, IMM, 0X77);
build_special_1 (LOCK);
build_special_2 (PAUSE);
assemble (OPERATION_ADD_F, SIZE_16B,
TYPE_VARIABLE, 12,
TYPE_REGISTER, OPERAND_REGISTER_A);
assemble (OPERATION_ADD_F, SIZE_8B,
TYPE_REGISTER, OPERAND_REGISTER_3,
TYPE_CONSTANT, 0X77);
for (int index = 0; index < token_count; ++index) {
printf ("%02X \n", token_array [index]);
for (index = 0; index < output_count; ++index) {
printf ("%02X \n", output_array [index]);
}
free (token_array);
free (output_array);
return (0);
}
//~xor rcx rdx
//~48 31 D1
//~WORKS AS EXPECTED!
//~90 48 11 D1
//~90 13 0D 14 10 00 00
//~90 66 44 11 15 09 10 00 00
//~90 80 D3 77

View File

@ -153,19 +153,6 @@ entry $
nop
nop
nop
adc rcx, rdx; 48 31 D1
nop
adc ecx, [x4]; 33 0D 14 10 00 00
nop
adc [x2], r10w; 66 44 31 15 09 10 00 00
nop
adc bl, 077h; 80 F3 77
nop
nop
nop
nop
enter 2, 2
nop
@ -180,6 +167,77 @@ entry $
sysexit
nop
cpuid
nop
movbe rax, [x8]
nop
movbe rcx, [x8]
nop
movsq
nop
neg rax
nop
neg dword[x4]
nop
nop
nop
nop
inc byte[x1]
nop
inc word[x2]
nop
inc dword[x4]
nop
inc qword[x8]
nop
inc cl
nop
inc cx
nop
inc ecx
nop
inc rcx
nop
inc r9b
nop
inc r9w
nop
inc r9d
nop
inc r9
nop
nop
nop
nop
adc rcx, rdx; 48 31 D1
nop
adc ecx, [x4]; 33 0D 14 10 00 00
nop
adc [x2], r10w; 66 44 31 15 09 10 00 00
nop
adc bl, 077h; 80 F3 77
;~assemble (ADC, D64, REG, R1, REG, R2);
;~assemble (ADC, D32, REG, R1, MEM, 12);
;~assemble (ADC, D16, MEM, 12, REG, R10);
;~assemble (ADC, D8, REG, R3, IMM, 0X77);
;~48 11 D1
;~13 0D 14 10 00 00
;~66 44 11 15 09 10 00 00
;~80 D3 77
;~48
;~11
;~D1
;~13
;~0D
;~66
;~44
;~11
;~15
;~80
;~D3
nop

View File

@ -1,155 +1,137 @@
#include "assembler.h"
static next token_count = 0;
static byte * token_array = NULL;
#include <stdlib.h>
static void token_print (byte data) {
token_array [token_count] = data;
token_count += 1;
}
static inline form valid (form data) { return ((data >= 0) && (data <= 15)); }
static inline form lower (form data) { return ((data >= 0) && (data <= 7)); }
static inline form upper (form data) { return ((data >= 8) && (data <= 15)); }
static inline
void format_short_prefix (void) {
token_print (0X66);
}
static inline
void format_long_prefix (size_index size,
type_index to,
form destination,
type_index from,
form source) {
token_print (0X40 +
0X01 * ((to == TYPE_REGISTER) && (upper (destination))) +
0X04 * ((from == TYPE_REGISTER) && (upper (source))) +
0X08 * (size == SIZE_64B));
}
static inline
void format_register_direction (size_index size,
form destination,
form source) {
token_print (0XC0 +
0X01 * (destination % 8) +
0X08 * (source % 8));
}
/*
static inline
void format_register_indirection (size_index size,
form destination) {
byte format = 0XF0;
format += destination % 8;
token_print (format);
}
gcc -c -ansi -Wall -Wextra -Wpedantic -Werror:
-- warns about trailing comma in enumerations.
-- kept because of chad coding standard.
-- unused functions for now, obviously...
clang -c -ansi -Weverything -Werror:
-- exactly same warnings as with gcc above.
splint -fcnuse +boolint +charint assembler.c:
-- we obviously ignore unused functions for now.
-- we assume bool is int, which is true.
-- we assume char is int, which is true.
-- assembler.c:167:13: Function fabs shadows outer declaration
-- ^ function from <math.h>, which we don't even use.
splint assembler.h:
-- no warnings at all.
*/
static inline
void format_register_redirection (size_index size,
form direction) {
token_print (0X05 +
0X08 * (direction % 8));
#define REGULAR_START (ADD)
#define REGULAR_COUNT (UMUL - REGULAR_START)
#define IRREGULAR_START (UMUL)
#define IRREGULAR_COUNT (NOP - IRREGULAR_START)
#define SPECIAL_1_START (NOP)
#define SPECIAL_1_COUNT (SYSENTER - SPECIAL_1_START)
#define SPECIAL_2_START (SYSENTER)
#define SPECIAL_2_COUNT (ENTER - SPECIAL_2_START)
typedef signed int form;
typedef unsigned int next;
typedef unsigned char byte;
static next input_count; /* SHOULD I EXPOSE THESE? */
static form * input_array;
static next output_count;
static byte * output_array;
static void place (form when, byte data) {
output_array [output_count] = data;
output_count += (next) when;
}
static inline
void format_constant (size_index size) {
token_print (0X80 +
0X01 * (size != SIZE_8B));
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)); }
static void build_short_prefix (form when) {
place (when, 0X66);
}
static inline
void format_regular_instruction (byte format,
size_index size,
type_index to,
form destination,
type_index from,
form source) {
//~format += 0X01 * (size != SIZE_8B);
//~format += 0X02 * ((to == TYPE_REGISTER) && (from == TYPE_VARIABLE));
//~format += 0XC0 * ((to == TYPE_REGISTER) && (from == TYPE_CONSTANT));
//~format += 0X04 * ((to == TYPE_VARIABLE) && (from == TYPE_CONSTANT));
//~if ((to == TYPE_REGISTER) && (from == TYPE_CONSTANT)) {
//~format += destination % 8;
//~}
//~token_print (format);
token_print (format +
destination % 8 * ((to == TYPE_REGISTER) && (from == TYPE_CONSTANT)) +
0X01 * (size != SIZE_8B) +
0X02 * ((to == TYPE_REGISTER) && (from == TYPE_VARIABLE)) +
0XC0 * ((to == TYPE_REGISTER) && (from == TYPE_CONSTANT)) +
0X04 * ((to == TYPE_VARIABLE) && (from == TYPE_CONSTANT)));
static void build_long_prefix (form when,
size_index size,
type_index to,
form destination,
type_index from,
form source) {
place (when, (byte) (0X40
+ 0X01 * ((to == REG) && (upper (destination)))
+ 0X04 * ((from == REG) && (upper (source)))
+ 0X08 * (size == D64)));
}
static inline
void assemble_enter (form dynamic_storage,
form nesting_level) {
token_print (0XC8);
token_print ((dynamic_storage / 1) % 256); // FIX LATER
token_print ((dynamic_storage / 256) % 256);
token_print ((nesting_level / 1) % 256);
static void build_register_direction (form when,
form destination,
form source) { /* LENGTH */
place (when, (byte) (0XC0 + 0X01 * (destination % 8) + 0X08 * (source % 8)));
}
static inline void assemble_leave (void) { token_print (0XC9); }
static inline void assemble_system_call (void) { token_print (0X0F); token_print (0X05); }
static inline void assemble_system_return (void) { token_print (0X0F); token_print (0X07); }
static inline void assemble_system_enter (void) { token_print (0X0F); token_print (0X34); }
static inline void assemble_system_exit (void) { token_print (0X0F); token_print (0X35); }
static inline void assemble_cpu_identifier (void) { token_print (0X0F); token_print (0XA2); }
static inline
void assemble (operation_index operation,
size_index size,
type_index to,
form destination,
type_index from,
form source) {
byte code = 0X00;
if (size == SIZE_16B) {
format_short_prefix ();
}
if ((size == SIZE_64B)
|| ((to == TYPE_REGISTER) && (upper (destination)))
|| ((from == TYPE_REGISTER) && (upper (source)))) {
format_long_prefix (size, to, destination, from, source);
}
if (from == TYPE_CONSTANT) {
format_constant (size);
}
switch (operation) {
case OPERATION_ADD: code = 0X00; break;
case OPERATION_OR: code = 0X08; break;
case OPERATION_ADD_F: code = 0X10; break;
case OPERATION_SUBTRACT_F: code = 0X18; break;
case OPERATION_AND: code = 0X20; break;
case OPERATION_SUBTRACT: code = 0X28; break;
case OPERATION_XOR: code = 0X30; break;
case OPERATION_COMPARE: code = 0X38; break;
default: break;
}
format_regular_instruction (code, size, to, destination, from, source);
if ((to == TYPE_REGISTER) && (from == TYPE_REGISTER)) {
format_register_direction (size, destination, source);
}
if ((to == TYPE_REGISTER) && (from == TYPE_VARIABLE)) {
format_register_redirection (size, destination);
}
if ((to == TYPE_VARIABLE) && (from == TYPE_REGISTER)) {
format_register_redirection (size, source);
}
static void build_register_redirection (form when,
form direction) {
place (when, (byte) (0X05 + 0X08 * (direction % 8)));
}
static void build_constant (form when,
size_index size) {
place (when, (byte) (0X80 + 0X01 * (size != D8)));
}
static void build_regular_instruction (form when,
byte code,
size_index size,
type_index to,
form destination,
type_index from) {
place (when, (byte) (code
+ destination % 8 * ((to == REG) && (from == IMM))
+ 0X01 * (size != D8)
+ 0X02 * ((from == MEM) && (to == REG))
+ 0X04 * ((from == IMM) && (to == MEM))
+ 0XC0 * ((from == IMM) && (to == REG))));
}
static void build_regular (operation_index operation,
size_index size,
type_index to,
form destination,
type_index from,
form source) {
build_short_prefix (size == D16);
build_long_prefix ((size == D64)
|| ((to == REG) && (upper (destination)))
|| ((from == REG) && (upper (source))),
size, to, destination, from, source);
build_constant (from == IMM, size);
build_regular_instruction (1, (byte) (0X08 * operation),
size, to, destination, from);
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);
}
static void build_special_1 (operation_index operation) {
const byte data [1 * SPECIAL_1_COUNT] = {
0X90, 0XC3, 0XCB, 0XC9, 0XF0, 0XF4
};
place (1, data [operation - SPECIAL_1_START]);
}
static void build_special_2 (operation_index operation) {
const byte data [2 * SPECIAL_2_COUNT] = {
0X0F, 0X0F, 0X0F, 0X0F, 0XF3, 0X0F,
0X34, 0X35, 0X05, 0X07, 0X90, 0XA2
};
place (1, data [operation - SPECIAL_2_START]);
place (1, data [operation - SPECIAL_2_START + SPECIAL_2_COUNT]);
}

View File

@ -1,40 +1,48 @@
#ifndef ASSEMBLER_H
#define ASSEMBLER_H
#include <stdlib.h>
typedef enum {
SIZE_256B, SIZE_128B, SIZE_64B,
SIZE_32B, SIZE_16B, SIZE_8B,
D64, D32, D16, D8,
} size_index;
typedef enum {
TYPE_REGISTER, TYPE_VARIABLE, TYPE_CONSTANT,
NIL, REG, MEM, IMM,
} type_index;
typedef enum {
OPERATION_MOVE, OPERATION_ADD, OPERATION_SUBTRACT,
OPERATION_MULTIPLY, OPERATION_DIVIDE, OPERATION_MODULUS,
OPERATION_COMPARE, OPERATION_JUMP, OPERATION_XOR,
OPERATION_AND, OPERATION_OR, OPERATION_NOT,
OPERATION_IS, OPERATION_ABOVE, OPERATION_BELOW,
OPERATION_IF, OPERATION_INCREMENT, OPERATION_DECREMENT,
OPERATION_SYSTEM, OPERATION_CALL, OPERATION_RETURN,
OPERATION_ENTER, OPERATION_LEAVE, OPERATION_EXIT,
OPERATION_ADD_F, OPERATION_SUBTRACT_F,
ADD, OR, ADC, SBB,
AND, SUB, XOR, CMP,
UMUL, UDIV, IMUL, IDIV,
INC, DEC, NOT, NEG,
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,
PUSH, POP, BSWAP, TEST,
RCL, RCR, ROL, ROR,
SHL, SHR, SAL, SAR,
REP, REPE, REPNE, REPZ,
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;
typedef enum {
OPERAND_REGISTER_0, OPERAND_REGISTER_1, OPERAND_REGISTER_2,
OPERAND_REGISTER_3, OPERAND_REGISTER_4, OPERAND_REGISTER_5,
OPERAND_REGISTER_6, OPERAND_REGISTER_7, OPERAND_REGISTER_8,
OPERAND_REGISTER_9, OPERAND_REGISTER_A, OPERAND_REGISTER_B,
OPERAND_REGISTER_C, OPERAND_REGISTER_D, OPERAND_REGISTER_E,
OPERAND_REGISTER_F, OPERAND_REFERENCE, OPERAND_DEREFERENCE,
R0, R1, R2, R3,
R4, R5, R6, R7,
R8, R9, R10, R11,
R12, R13, R14, R15,
} operand_index;
typedef signed int form;
typedef unsigned int next;
typedef unsigned char byte;
#endif