diff --git a/libjas/include/instruction.h b/libjas/include/instruction.h index 581aee2..a8398c8 100644 --- a/libjas/include/instruction.h +++ b/libjas/include/instruction.h @@ -155,6 +155,26 @@ typedef struct { */ instr_encode_table_t instr_get_tab(instruction_t instr); +/** + * Function for generating an instruction struct with the given + * instruction type and operands. The function is used to create + * a Jas buffer and write it into a instruction, similar to the + * `db` and `dw` directives in NASM, but this uses the size and + * variadic arguments to write the bytes into the buffer. + * + * @param data_sz The size of the data to write + * @param ... The data to write into the buffer + * + * @return The instruction struct + * + * @example The **Jas** function call of: + * > instr_write_bytes(7, 0x48, 0x89, 0x80, 0xff, 0x00, 0x00, 0x00); + * + * Is equivalent to: (In NASM) + * > db 0x48, 0x89, 0x80, 0xff, 0x00, 0x00, 0x00 + */ +instruction_t instr_write_bytes(size_t data_sz, ...); + /** * Macros for defining the instruction operands in a more readable * form for passing into the `instr_gen` function. The macros are diff --git a/libjas/instruction.c b/libjas/instruction.c index 8efc0e8..67b6b3e 100644 --- a/libjas/instruction.c +++ b/libjas/instruction.c @@ -104,4 +104,25 @@ instruction_t instr_gen(enum instructions instr, uint8_t operand_count, ...) { .instr = instr, .operands = operands, }; +} + +instruction_t instr_write_bytes(size_t data_sz, ...) { + buffer_t data = BUF_NULL; + va_list args; + va_start(args, data_sz); + + for (size_t i = 0; i < data_sz; i++) { + const uint8_t byte = va_arg(args, uint8_t); + buf_write_byte(&data, byte); + } + + // clang-format off + return (instruction_t){ + .instr = INSTR_DIR_WRT_BUF, + .operands = (operand_t[]){ + op_construct_operand(OP_MISC, 0, &data, NULL), + OP_NONE, OP_NONE, OP_NONE, + }, + }; + // clang-format on } \ No newline at end of file