Skip to content

Commit

Permalink
Revised op_write_opcode function (#25)
Browse files Browse the repository at this point in the history
* Revised `op_write_opcode` function

Happy new year, this pull has revised the `op_write_opcode` function,
which was previously mis-interpreted. According to the Intel x86 docs,
a instruction **including** a byte-sized operand **MUST** use the byte
instruction opcode. This is demonstrated in the MOVZX instruction's docs
on 4-136 Vol. 2B where a seperate opcode is used with `r/m8`.

* Added *normal* opcode

In the previous commit, 20efed7,
I've forgotten to return the normal opcode (Slap slap) which caused
some of the unit tests to fail where the normal operands are given.
  • Loading branch information
cheng-alvin authored Jan 1, 2025
1 parent 5914670 commit 0f69801
Showing 1 changed file with 4 additions and 15 deletions.
19 changes: 4 additions & 15 deletions libjas/operand.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,26 +64,15 @@ uint8_t op_sizeof(enum operands input) {
return 0;
}

/* Instructions containing a byte-sized operand uses the byte opcode (see. 4-136 Vol. 2B, MOVZX—Move With Zero-Extend) */
uint8_t *op_write_opcode(operand_t *op_arr, instr_encode_table_t *instr_ref) {
if (!instr_ref->has_byte_opcode) return instr_ref->opcode;

// According to Oracle's <x86 Assembly Language Reference Manual>
// (Yeah seriously - Oracle has a x86 Assembly Language Reference Manual)
// Only when *BOTH* operands are byte-sized, the opcode will also be byte-sized
// So, wel'll check if they are *BOTH* byte sized then write that.

const uint8_t reference = op_sizeof(op_arr[0].type);
const uint8_t sizes[] =
{reference, op_sizeof(op_arr[1].type),
op_sizeof(op_arr[2].type), op_sizeof(op_arr[3].type)};

bool sizes_are_byte = reference == 8;
for (unsigned char i = 0; i < 4; i++) {
for (uint8_t i = 0; i < 4; i++) {
if (op_arr[i].type == OP_NULL) break;
if (sizes[i] != 8 && sizes_are_byte) sizes_are_byte = false;
if (op_byte(op_arr[i].type)) return instr_ref->byte_instr_opcode;
continue;
}

if (sizes_are_byte) return instr_ref->byte_instr_opcode;
return instr_ref->opcode;
}

Expand Down

0 comments on commit 0f69801

Please sign in to comment.