Добрый день. Я не являюсь экспертом в области computer science и к тому же, в разработке компиляторов. Знаю, что у intel процессора можно провести анализ и поделить на группы то или иное действие, чтобы составить грамотный код. Сначала я анализировал опкоды, всё сравнивал, нашел некоторую логику, но как бы не хотелось, в других опкодах [в построении опкодов] я логику не наблюдал, и решил сделать простым монотонным способом, то-есть объявить каждый опкод процессора.
Выглядит это не сложно, и поэтому кажется, что не очень круто. Как вы думаете, стоит ли провести нормальный анализ и поделить на составные части, ведь к примеру, опкоды, которые имеют у себя в начале 0x80-0x83 опкоды имеют под собой логичную трактовку и можно сделать парсер для реверс инжиниринга, но дальнейшие опкоды я так и не понял.
В итоге, я тупо добавляю все опкоды в простую структуру, файл чьей предоставлю в конце сообщения.
Я прикупил несколько нетбуков asus eee pc 700 и одну хорошую батарею. На этих нетбуках был windows xp. На одном оставит xp, а на другом поставил openbsd, но места оказалось мало, даже без иксов и игр, так как требуется поставить туда компилятор, а он весит много.
Так как у меня есть желание делать свою ось, чтобы кайфовать от процесса, я решил сначала написать свой компилятор ассемблера, и думаю какой язык высокого уровня воспроизвести, C или свой написать? Это риторический вопрос. На тех нетбуках должен быть простой процессор. Если мне удасться написать всё что задумал, то будет хорошее резюме, но не только резюме меня тянет этим заниматься. У меня есть пару книг, которые я бы хотел прочесть, а без практики их не интересно читать.
Вот код как выглядит составление ассемблерных опкодов.
#include <stdio.h>
#include <stdint.h>
enum {
AAA,
AAD,
AAM,
AAS,
ADC,
ADD,
AND
};
#define MAX_BYTES_IN_OPCODE_PREFIX 4
#define REQUIRED_NO 0
#define REQUIRED_VAL 1
enum {
RM8_R8,
RM16_R16,
R8_RM8,
R16_RM16,
AL_IMM8,
AX_IMM16,
RM8_IMM8,
RM16_IMM16,
RM16_IMM8,
VALUE_NO_TYPE
};
#define MAY_NO 0
#define MAY_16_32_BITS 1
#define REQUIRED_NO_SECOND_REG 0
#define REQUIRED_SECOND_REG 1
struct opcode_definition {
uint32_t val;
const char *str_val;
uint32_t is_required_val;
void (*build_bytes) (struct opcode_definition *def);
uint8_t prefix_bytes[4];
uint32_t prefix_size;
uint32_t value_type;
uint32_t total_operator;
uint32_t may_32;
uint32_t need_second_reg;
uint8_t second_reg[1];
};
#define BYTE_BUILDER1(b0) \
{b0}
#define BYTE_BUILDER2(b0, b1) \
{b0, b1}
#define BYTE_BUILDER3(b0, b1, b2) \
{b0, b1, b2}
#define BYTE_BUILDER4(b0, b1, b2, b3) \
{b0, b1, b2, b3}
#define DEFINE_OPCODE_ARRAY() \
static struct opcode_definition opcodes[] = {
#define DEFINE_OPCODE_ARRAY_END() \
};
#define ADD_OPCODE(value, required_val, func_byte_builder, sprefix_size, svalue_type, smay_16_32, is_need_second_reg, sub_reg, sbytes) \
{.val = value, .str_val = #value, .is_required_val = required_val, .build_bytes = func_byte_builder, \
.prefix_size = sprefix_size, .value_type = svalue_type, \
.prefix_bytes = sbytes, .may_32 = smay_16_32, .second_reg = sub_reg, .need_second_reg = is_need_second_reg},
DEFINE_OPCODE_ARRAY()
ADD_OPCODE(AAA, REQUIRED_NO, NULL, 1, VALUE_NO_TYPE, MAY_NO, REQUIRED_NO_SECOND_REG, 0, BYTE_BUILDER1(0x37))
ADD_OPCODE(AAD, REQUIRED_NO, NULL, 2, VALUE_NO_TYPE, MAY_NO, REQUIRED_NO_SECOND_REG, 0, BYTE_BUILDER2(0xd5, 0x0a))
ADD_OPCODE(AAM, REQUIRED_NO, NULL, 2, VALUE_NO_TYPE, MAY_NO, REQUIRED_NO_SECOND_REG, 0, BYTE_BUILDER2(0xd4, 0x0a))
ADD_OPCODE(AAS, REQUIRED_NO, NULL, 1, VALUE_NO_TYPE, MAY_NO, REQUIRED_NO_SECOND_REG, 0, BYTE_BUILDER1(0x3f))
ADD_OPCODE(ADC, REQUIRED_VAL, NULL, 1, RM8_R8, MAY_NO, REQUIRED_NO_SECOND_REG, 0, BYTE_BUILDER1(0x10))
ADD_OPCODE(ADC, REQUIRED_VAL, NULL, 1, RM16_R16, MAY_16_32_BITS, REQUIRED_NO_SECOND_REG, 0, BYTE_BUILDER1(0x11))
ADD_OPCODE(ADC, REQUIRED_VAL, NULL, 1, R8_RM8, MAY_NO, REQUIRED_NO_SECOND_REG, 0, BYTE_BUILDER1(0x12))
ADD_OPCODE(ADC, REQUIRED_VAL, NULL, 1, R16_RM16, MAY_16_32_BITS, REQUIRED_NO_SECOND_REG, 0, BYTE_BUILDER1(0x13))
ADD_OPCODE(ADC, REQUIRED_VAL, NULL, 1, AL_IMM8, MAY_NO, REQUIRED_NO_SECOND_REG, 0, BYTE_BUILDER1(0x14))
ADD_OPCODE(ADC, REQUIRED_VAL, NULL, 1, AX_IMM16, MAY_NO, REQUIRED_NO_SECOND_REG, 0, BYTE_BUILDER1(0x15))
ADD_OPCODE(ADC, REQUIRED_VAL, NULL, 1, RM8_IMM8, MAY_NO, REQUIRED_SECOND_REG, BYTE_BUILDER1(0x02), BYTE_BUILDER1(0x80))
ADD_OPCODE(ADC, REQUIRED_VAL, NULL, 1, RM16_IMM16, MAY_16_32_BITS, REQUIRED_SECOND_REG, BYTE_BUILDER1(0x02), BYTE_BUILDER1(0x81))
ADD_OPCODE(ADC, REQUIRED_VAL, NULL, 1, RM16_IMM8, MAY_16_32_BITS, REQUIRED_SECOND_REG, BYTE_BUILDER1(0x02), BYTE_BUILDER1(0x82))
ADD_OPCODE(ADD, REQUIRED_VAL, NULL, 1, RM8_R8, MAY_NO, REQUIRED_NO_SECOND_REG, 0, BYTE_BUILDER1(0x00))
ADD_OPCODE(ADD, REQUIRED_VAL, NULL, 1, RM16_R16, MAY_16_32_BITS, REQUIRED_NO_SECOND_REG, 0, BYTE_BUILDER1(0x01))
ADD_OPCODE(ADD, REQUIRED_VAL, NULL, 1, R8_RM8, MAY_NO, REQUIRED_NO_SECOND_REG, 0, BYTE_BUILDER1(0x02))
ADD_OPCODE(ADD, REQUIRED_VAL, NULL, 1, R16_RM16, MAY_16_32_BITS, REQUIRED_NO_SECOND_REG, 0, BYTE_BUILDER1(0x03))
ADD_OPCODE(ADD, REQUIRED_VAL, NULL, 1, AL_IMM8, MAY_NO, REQUIRED_NO_SECOND_REG, 0, BYTE_BUILDER1(0x04))
ADD_OPCODE(ADD, REQUIRED_VAL, NULL, 1, AX_IMM16, MAY_NO, REQUIRED_NO_SECOND_REG, 0, BYTE_BUILDER1(0x05))
ADD_OPCODE(ADD, REQUIRED_VAL, NULL, 1, RM8_IMM8, MAY_NO, REQUIRED_SECOND_REG, BYTE_BUILDER1(0x00), BYTE_BUILDER1(0x80))
ADD_OPCODE(ADD, REQUIRED_VAL, NULL, 1, RM16_IMM16, MAY_16_32_BITS, REQUIRED_SECOND_REG, BYTE_BUILDER1(0x00), BYTE_BUILDER1(0x81))
ADD_OPCODE(ADD, REQUIRED_VAL, NULL, 1, RM16_IMM8, MAY_16_32_BITS, REQUIRED_SECOND_REG, BYTE_BUILDER1(0x00), BYTE_BUILDER1(0x83))
ADD_OPCODE(AND, REQUIRED_VAL, NULL, 1, RM8_R8, MAY_NO, REQUIRED_NO_SECOND_REG, 0, BYTE_BUILDER1(0x20))
ADD_OPCODE(AND, REQUIRED_VAL, NULL, 1, RM16_R16, MAY_16_32_BITS, REQUIRED_NO_SECOND_REG, 0, BYTE_BUILDER1(0x21))
ADD_OPCODE(AND, REQUIRED_VAL, NULL, 1, R8_RM8, MAY_NO, REQUIRED_NO_SECOND_REG, 0, BYTE_BUILDER1(0x22))
ADD_OPCODE(AND, REQUIRED_VAL, NULL, 1, R16_RM16, MAY_16_32_BITS, REQUIRED_SECOND_REG, 0, BYTE_BUILDER1(0x23))
ADD_OPCODE(AND, REQUIRED_VAL, NULL, 1, AL_IMM8, MAY_NO, REQUIRED_NO_SECOND_REG, 0, BYTE_BUILDER1(0x24))
ADD_OPCODE(AND, REQUIRED_VAL, NULL, 1, AX_IMM16, MAY_16_32_BITS, REQUIRED_NO_SECOND_REG, 0, BYTE_BUILDER1(0x25))
ADD_OPCODE(AND, REQUIRED_VAL, NULL, 1, RM8_IMM8, MAY_NO, REQUIRED_SECOND_REG, BYTE_BUILDER1(0x04), BYTE_BUILDER1(0x80))
ADD_OPCODE(AND, REQUIRED_VAL, NULL, 1, RM16_IMM16, MAY_16_32_BITS, REQUIRED_SECOND_REG, BYTE_BUILDER1(0x04), BYTE_BUILDER1(0x81))
ADD_OPCODE(AND, REQUIRED_VAL, NULL, 1, RM16_IMM8, MAY_16_32_BITS, REQUIRED_SECOND_REG, BYTE_BUILDER1(0x04), BYTE_BUILDER1(0x83))
DEFINE_OPCODE_ARRAY_END()