2021-01-15 23:16:01 +00:00
|
|
|
|
//
|
|
|
|
|
// Instruction.hpp
|
|
|
|
|
// Clock Signal
|
|
|
|
|
//
|
|
|
|
|
// Created by Thomas Harte on 1/15/21.
|
|
|
|
|
// Copyright © 2021 Thomas Harte. All rights reserved.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
#ifndef InstructionSets_x86_Instruction_h
|
|
|
|
|
#define InstructionSets_x86_Instruction_h
|
|
|
|
|
|
|
|
|
|
#include <cstdint>
|
|
|
|
|
|
2021-01-16 02:30:30 +00:00
|
|
|
|
namespace InstructionSet {
|
2021-01-15 23:16:01 +00:00
|
|
|
|
namespace x86 {
|
|
|
|
|
|
2021-01-15 23:27:55 +00:00
|
|
|
|
/*
|
|
|
|
|
Operations are documented below to establish expectations as to which
|
|
|
|
|
instruction fields will be meaningful for each; this is a work-in-progress
|
|
|
|
|
and may currently contain errors in the opcode descriptions — especially
|
|
|
|
|
where implicit register dependencies are afoot.
|
|
|
|
|
*/
|
2021-01-15 23:16:01 +00:00
|
|
|
|
enum class Operation: uint8_t {
|
|
|
|
|
Invalid,
|
|
|
|
|
|
|
|
|
|
/// ASCII adjust after addition; source will be AL and destination will be AX.
|
|
|
|
|
AAA,
|
|
|
|
|
/// ASCII adjust before division; destination will be AX and source will be a multiplier.
|
|
|
|
|
AAD,
|
|
|
|
|
/// ASCII adjust after multiplication; destination will be AX and source will be a divider.
|
|
|
|
|
AAM,
|
|
|
|
|
/// ASCII adjust after subtraction; source will be AL and destination will be AX.
|
|
|
|
|
AAS,
|
2021-01-16 02:07:02 +00:00
|
|
|
|
/// Decimal adjust after addition; source and destination will be AL.
|
|
|
|
|
DAA,
|
|
|
|
|
/// Decimal adjust after subtraction; source and destination will be AL.
|
|
|
|
|
DAS,
|
2021-01-16 01:48:31 +00:00
|
|
|
|
|
2021-01-15 23:16:01 +00:00
|
|
|
|
/// Convert byte into word; source will be AL, destination will be AH.
|
|
|
|
|
CBW,
|
|
|
|
|
/// Convert word to double word; source will be AX and destination will be DX.
|
|
|
|
|
CWD,
|
2021-01-16 02:07:02 +00:00
|
|
|
|
|
2021-01-15 23:27:55 +00:00
|
|
|
|
/// Escape, for a coprocessor; perform the bus cycles necessary to read the source and destination and perform a NOP.
|
|
|
|
|
ESC,
|
2021-01-16 01:48:31 +00:00
|
|
|
|
|
2021-01-15 23:52:59 +00:00
|
|
|
|
/// Stops the processor until the next interrupt is fired.
|
2021-01-15 23:27:55 +00:00
|
|
|
|
HLT,
|
2021-01-16 01:48:31 +00:00
|
|
|
|
/// Waits until the WAIT input is asserted; if an interrupt occurs then it is serviced but returns to the WAIT.
|
|
|
|
|
WAIT,
|
|
|
|
|
|
|
|
|
|
/// Add with carry; source, destination, operand and displacement will be populated appropriately.
|
|
|
|
|
ADC,
|
|
|
|
|
/// Add; source, destination, operand and displacement will be populated appropriately.
|
|
|
|
|
ADD,
|
|
|
|
|
/// Subtract with borrow; source, destination, operand and displacement will be populated appropriately.
|
|
|
|
|
SBB,
|
|
|
|
|
/// Subtract; source, destination, operand and displacement will be populated appropriately.
|
|
|
|
|
SUB,
|
2021-01-15 23:52:59 +00:00
|
|
|
|
/// Unsigned multiply; multiplies the source value by AX or AL, storing the result in DX:AX or AX.
|
|
|
|
|
MUL,
|
|
|
|
|
/// Signed multiply; multiplies the source value by AX or AL, storing the result in DX:AX or AX.
|
2021-01-15 23:27:55 +00:00
|
|
|
|
IMUL,
|
2021-01-16 01:48:31 +00:00
|
|
|
|
/// Unsigned divide; divide the source value by AX or AL, storing the quotient in AL and the remainder in AH.
|
|
|
|
|
DIV,
|
|
|
|
|
/// Signed divide; divide the source value by AX or AL, storing the quotient in AL and the remainder in AH.
|
|
|
|
|
IDIV,
|
|
|
|
|
|
2021-01-16 02:07:02 +00:00
|
|
|
|
/// Increment; source, destination, operand and displacement will be populated appropriately.
|
|
|
|
|
INC,
|
|
|
|
|
/// Decrement; source, destination, operand and displacement will be populated appropriately.
|
|
|
|
|
DEC,
|
2021-01-16 01:48:31 +00:00
|
|
|
|
|
2021-01-15 23:52:59 +00:00
|
|
|
|
/// Reads from the port specified by source to the destination.
|
2021-01-15 23:27:55 +00:00
|
|
|
|
IN,
|
2021-01-15 23:52:59 +00:00
|
|
|
|
/// Writes from the port specified by destination from the source.
|
|
|
|
|
OUT,
|
2021-01-16 01:48:31 +00:00
|
|
|
|
|
2021-01-15 23:27:55 +00:00
|
|
|
|
// Various jumps; see the displacement to calculate targets.
|
2021-01-15 23:16:01 +00:00
|
|
|
|
JO, JNO, JB, JNB, JE, JNE, JBE, JNBE,
|
|
|
|
|
JS, JNS, JP, JNP, JL, JNL, JLE, JNLE,
|
2021-01-15 23:27:55 +00:00
|
|
|
|
|
2021-01-16 01:48:31 +00:00
|
|
|
|
/// Far call; see the segment() and offset() fields.
|
|
|
|
|
CALLF,
|
|
|
|
|
/// Displacement call; followed by a 16-bit operand providing a call offset.
|
|
|
|
|
CALLD,
|
|
|
|
|
/// Near call.
|
|
|
|
|
CALLN,
|
|
|
|
|
/// Return from interrupt.
|
|
|
|
|
IRET,
|
|
|
|
|
/// Near return; if source is not ::None then it will be an ::Immediate indicating how many additional bytes to remove from the stack.
|
|
|
|
|
RETF,
|
|
|
|
|
/// Far return; if source is not ::None then it will be an ::Immediate indicating how many additional bytes to remove from the stack.
|
|
|
|
|
RETN,
|
2021-01-15 23:52:59 +00:00
|
|
|
|
/// Near jump; if an operand is not ::None then it gives an absolute destination; otherwise see the displacement.
|
2021-01-15 23:16:01 +00:00
|
|
|
|
JMPN,
|
2021-01-15 23:52:59 +00:00
|
|
|
|
/// Far jump to the indicated segment and offset.
|
2021-01-15 23:16:01 +00:00
|
|
|
|
JMPF,
|
2021-01-15 23:52:59 +00:00
|
|
|
|
/// Relative jump performed only if CX = 0; see the displacement.
|
|
|
|
|
JPCX,
|
2021-01-16 01:48:31 +00:00
|
|
|
|
/// Generates a software interrupt of the level stated in the operand.
|
|
|
|
|
INT,
|
|
|
|
|
/// Generates a software interrupt of level 3.
|
|
|
|
|
INT3,
|
|
|
|
|
/// Generates a software interrupt of level 4 if overflow is set.
|
|
|
|
|
INTO,
|
|
|
|
|
|
2021-01-15 23:52:59 +00:00
|
|
|
|
/// Load status flags to AH.
|
|
|
|
|
LAHF,
|
|
|
|
|
/// Load status flags from AH.
|
|
|
|
|
SAHF,
|
|
|
|
|
/// Load a segment and offset from the source into DS and the destination.
|
|
|
|
|
LDS,
|
2021-01-16 01:48:31 +00:00
|
|
|
|
/// Load a segment and offset from the source into ES and the destination.
|
|
|
|
|
LES,
|
2021-01-15 23:52:59 +00:00
|
|
|
|
/// Computes the effective address of the source and loads it into the destination.
|
|
|
|
|
LEA,
|
2021-01-16 01:48:31 +00:00
|
|
|
|
|
2021-01-16 02:07:02 +00:00
|
|
|
|
/// Compare [bytes or words, per operation size]; source and destination implied to be DS:[SI] and ES:[DI].
|
|
|
|
|
CMPS,
|
2021-01-15 23:52:59 +00:00
|
|
|
|
/// Load string; reads from DS:SI into AL or AX, subject to segment override.
|
|
|
|
|
LODS,
|
|
|
|
|
/// Move string; moves a byte or word from DS:SI to ES:DI. If a segment override is provided, it overrides the the source.
|
|
|
|
|
MOVS,
|
2021-01-16 01:48:31 +00:00
|
|
|
|
/// Scan string; reads a byte or word from DS:SI and compares it to AL or AX.
|
|
|
|
|
SCAS,
|
|
|
|
|
/// Store string; store AL or AX to ES:DI.
|
|
|
|
|
STOS,
|
2021-01-15 23:52:59 +00:00
|
|
|
|
|
|
|
|
|
// Perform a possibly-conditional loop, decrementing CX. See the displacement.
|
|
|
|
|
LOOP, LOOPE, LOOPNE,
|
|
|
|
|
|
|
|
|
|
/// Loads the destination with the source.
|
|
|
|
|
MOV,
|
|
|
|
|
/// Negatives; source and destination point to the same thing, to negative.
|
|
|
|
|
NEG,
|
|
|
|
|
/// Logical NOT; source and destination point to the same thing, to negative.
|
|
|
|
|
NOT,
|
|
|
|
|
/// Logical AND; source, destination, operand and displacement will be populated appropriately.
|
|
|
|
|
AND,
|
|
|
|
|
/// Logical OR of source onto destination.
|
|
|
|
|
OR,
|
|
|
|
|
/// Logical XOR of source onto destination.
|
|
|
|
|
XOR,
|
|
|
|
|
/// NOP; no further fields.
|
|
|
|
|
NOP,
|
2021-01-16 01:48:31 +00:00
|
|
|
|
/// POP from the stack to destination.
|
|
|
|
|
POP,
|
|
|
|
|
/// POP from the stack to the flags register.
|
|
|
|
|
POPF,
|
|
|
|
|
/// PUSH the source to the stack.
|
|
|
|
|
PUSH,
|
|
|
|
|
/// PUSH the flags register to the stack.
|
|
|
|
|
PUSHF,
|
|
|
|
|
/// Rotate the destination left through carry the number of bits indicated by source.
|
|
|
|
|
RCL,
|
|
|
|
|
/// Rotate the destination right through carry the number of bits indicated by source.
|
|
|
|
|
RCR,
|
|
|
|
|
/// Rotate the destination left the number of bits indicated by source.
|
|
|
|
|
ROL,
|
|
|
|
|
/// Rotate the destination right the number of bits indicated by source.
|
|
|
|
|
ROR,
|
|
|
|
|
/// Arithmetic shift left the destination by the number of bits indicated by source.
|
|
|
|
|
SAL,
|
|
|
|
|
/// Arithmetic shift right the destination by the number of bits indicated by source.
|
|
|
|
|
SAR,
|
|
|
|
|
/// Logical shift right the destination by the number of bits indicated by source.
|
|
|
|
|
SHR,
|
2021-01-15 23:52:59 +00:00
|
|
|
|
|
2021-01-16 01:48:31 +00:00
|
|
|
|
/// Clear carry flag; no source or destination provided.
|
|
|
|
|
CLC,
|
|
|
|
|
/// Clear direction flag; no source or destination provided.
|
|
|
|
|
CLD,
|
|
|
|
|
/// Clear interrupt flag; no source or destination provided.
|
|
|
|
|
CLI,
|
|
|
|
|
/// Set carry flag.
|
|
|
|
|
STC,
|
|
|
|
|
/// Set decimal flag.
|
|
|
|
|
STD,
|
|
|
|
|
/// Set interrupt flag.
|
|
|
|
|
STI,
|
2021-01-16 02:07:02 +00:00
|
|
|
|
/// Complement carry flag; no source or destination provided.
|
|
|
|
|
CMC,
|
2021-01-15 23:16:01 +00:00
|
|
|
|
|
2021-01-16 02:07:02 +00:00
|
|
|
|
/// Compare; source, destination, operand and displacement will be populated appropriately.
|
|
|
|
|
CMP,
|
|
|
|
|
/// Sets flags based on the result of a logical AND of source and destination.
|
2021-01-16 01:48:31 +00:00
|
|
|
|
TEST,
|
|
|
|
|
|
|
|
|
|
/// Exchanges the contents of the source and destination.
|
|
|
|
|
XCHG,
|
|
|
|
|
|
|
|
|
|
/// Load AL with DS:[AL+BX].
|
|
|
|
|
XLAT,
|
2021-01-15 23:16:01 +00:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
enum class Size: uint8_t {
|
|
|
|
|
Implied = 0,
|
|
|
|
|
Byte = 1,
|
|
|
|
|
Word = 2,
|
|
|
|
|
DWord = 4,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
enum class Source: uint8_t {
|
|
|
|
|
None,
|
|
|
|
|
CS, DS, ES, SS,
|
|
|
|
|
|
|
|
|
|
AL, AH, AX,
|
|
|
|
|
BL, BH, BX,
|
|
|
|
|
CL, CH, CX,
|
|
|
|
|
DL, DH, DX,
|
|
|
|
|
|
|
|
|
|
SI, DI,
|
|
|
|
|
BP, SP,
|
|
|
|
|
|
|
|
|
|
IndBXPlusSI,
|
|
|
|
|
IndBXPlusDI,
|
|
|
|
|
IndBPPlusSI,
|
|
|
|
|
IndBPPlusDI,
|
|
|
|
|
IndSI,
|
|
|
|
|
IndDI,
|
|
|
|
|
DirectAddress,
|
|
|
|
|
IndBP,
|
|
|
|
|
IndBX,
|
|
|
|
|
|
|
|
|
|
Immediate
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
enum class Repetition: uint8_t {
|
|
|
|
|
None, RepE, RepNE
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
class Instruction {
|
|
|
|
|
public:
|
|
|
|
|
Operation operation = Operation::Invalid;
|
|
|
|
|
|
|
|
|
|
bool operator ==(const Instruction &rhs) const {
|
|
|
|
|
return
|
|
|
|
|
repetition_size_ == rhs.repetition_size_ &&
|
|
|
|
|
sources_ == rhs.sources_ &&
|
|
|
|
|
displacement_ == rhs.displacement_ &&
|
|
|
|
|
operand_ == rhs.operand_;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
// b0, b1: a Repetition;
|
|
|
|
|
// b2+: operation size.
|
|
|
|
|
uint8_t repetition_size_ = 0;
|
|
|
|
|
|
|
|
|
|
// b0–b5: source;
|
|
|
|
|
// b6–b11: destination;
|
|
|
|
|
// b12–b14: segment override;
|
|
|
|
|
// b15: lock.
|
|
|
|
|
uint16_t sources_ = 0;
|
|
|
|
|
|
|
|
|
|
// Unpackable fields.
|
|
|
|
|
int16_t displacement_ = 0;
|
|
|
|
|
uint16_t operand_ = 0; // ... or used to store a segment for far operations.
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
Source source() const { return Source(sources_ & 0x3f); }
|
|
|
|
|
Source destination() const { return Source((sources_ >> 6) & 0x3f); }
|
|
|
|
|
bool lock() const { return sources_ & 0x8000; }
|
|
|
|
|
Source segment_override() const { return Source((sources_ >> 12) & 7); }
|
|
|
|
|
|
|
|
|
|
Repetition repetition() const { return Repetition(repetition_size_ & 3); }
|
|
|
|
|
Size operation_size() const { return Size(repetition_size_ >> 2); }
|
|
|
|
|
|
|
|
|
|
uint16_t segment() const { return uint16_t(operand_); }
|
|
|
|
|
uint16_t offset() const { return uint16_t(displacement_); }
|
|
|
|
|
|
|
|
|
|
int16_t displacement() const { return displacement_; }
|
|
|
|
|
uint16_t operand() const { return operand_; }
|
|
|
|
|
|
|
|
|
|
Instruction() noexcept {}
|
|
|
|
|
Instruction(
|
|
|
|
|
Operation operation,
|
|
|
|
|
Source source,
|
|
|
|
|
Source destination,
|
|
|
|
|
bool lock,
|
|
|
|
|
Source segment_override,
|
|
|
|
|
Repetition repetition,
|
|
|
|
|
Size operation_size,
|
|
|
|
|
int16_t displacement,
|
|
|
|
|
uint16_t operand) noexcept :
|
|
|
|
|
operation(operation),
|
|
|
|
|
repetition_size_(uint8_t((int(operation_size) << 2) | int(repetition))),
|
|
|
|
|
sources_(uint16_t(
|
|
|
|
|
int(source) |
|
|
|
|
|
(int(destination) << 6) |
|
|
|
|
|
(int(segment_override) << 12) |
|
|
|
|
|
(int(lock) << 15)
|
|
|
|
|
)),
|
|
|
|
|
displacement_(displacement),
|
|
|
|
|
operand_(operand) {}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static_assert(sizeof(Instruction) <= 8);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endif /* InstructionSets_x86_Instruction_h */
|