//push imm8 is valid but not push r8 // no 8/32 bit mode for reg push public Push(DecodedTypes.IMyDecoded input, OpcodeSettings settings = OpcodeSettings.NONE) : base("PUSH", input, settings, // When pushing an immediate, the default(no prefix) is to push a immediate DWORD. // When pushing a register, the default is to push the QWORD register. A DWORD register cannot be pushed. // Both of these can however be WORD values if a SIZEOVR prefix is present. (input is DecodedTypes.Immediate) ? (ControlUnit.LPrefixBuffer.Contains(PrefixByte.SIZEOVR) ? RegisterCapacity.WORD : RegisterCapacity.DWORD) : (ControlUnit.LPrefixBuffer.Contains(PrefixByte.SIZEOVR) ? RegisterCapacity.WORD : RegisterCapacity.QWORD)) { Result = Fetch()[0]; // If an operand is a non-WORD/QWORD, it is sign extended to a QWORD // Here is a demonstration of this, // https://prnt.sc/outmtv // As you can see, 0x6A, which is PUSH IMM8, is sign extended to a QWORD. // https://prnt.sc/ouyxwd // Look at the points marked X. An immediate DWORD is pushed at 0x401035 then popped into RAX. // RAX became 0x12345678, the DWORD pushed, even though 0x1234 was pushed right before it. Intuition would // suggest that the value of RAX should be 0x123456781234, but as shown, 0x12345678 was extended to be a // QWORD rather than a DWORD. It is shown in the first screenshot that the bytes for an immediate DWORD push, // 68 78 56 34 12 // ^ // are used, so there is no kind of assembler interference happening. // Furthermore, this proves that immediate word pushes are not sign extended, even though the manual implies that // they ought to. As you can infer from the second screenshot, 0x1234 was popped into BX, then 0x*f2 was popped into // RCX. If 0x1234 had been extended, this would have been reflected in the value of RCX, as zeroes there would be zeroes // there, not the exact value pushed at 0x40102f. if (Result.Length == 1 || Result.Length == 4) { Result = Bitwise.SignExtend(Result, 8); } }
public Pop(DecodedTypes.IMyDecoded input, OpcodeSettings settings = OpcodeSettings.NONE) // Uses a specific register capacity derivation. If there is a SIZEOVR prefix, it is a WORD, otherwise a QWORD. There is no // other case. : base("POP", input, settings, (ControlUnit.LPrefixBuffer.Contains(PrefixByte.SIZEOVR)) ? RegisterCapacity.WORD : RegisterCapacity.QWORD) { }
public Jmp(DecodedTypes.IMyDecoded input, Condition condition = Condition.NONE, OpcodeSettings settings = OpcodeSettings.NONE, bool dwordOnly = false) // Determine the mnemonic. If there is a condition it needs to be disassembled, otherwise just JMP : base(condition == Condition.NONE ? "JMP" : "J" + Disassembly.DisassembleCondition(condition) , input , settings // BYTEMODE will always indicate that the capacity should be a byte, otherwise requires more work to derive. , (settings | OpcodeSettings.BYTEMODE) == settings ? RegisterCapacity.BYTE : JmpRegCap(dwordOnly)) { // Store the condition JmpCondition = condition; }
public Movx(DecodedTypes.IMyDecoded input, string mnemonic, bool signExtend, RegisterCapacity desiredSourceSize, OpcodeSettings settings = OpcodeSettings.NONE) : base(mnemonic, input, settings) { // Store the input for use in disassembly later. This is cheaper than working out the disassembly here, as not every caller // is going to disassemble. Input = input; // The size of the source. SourceSize = desiredSourceSize; // Store the size of destination as it is about to be changed. DestSize = Capacity; // Switch to the size of the source before fetching it. Capacity = desiredSourceSize; byte[] SourceBytes = Fetch()[1]; // Return back to the size the destination is. Capacity = DestSize; // Sign extend the source bytes to the size of the destination. Result = (signExtend) ? Bitwise.SignExtend(SourceBytes, (byte)Capacity) : Bitwise.ZeroExtend(SourceBytes, (byte)Capacity); }
public Dec(DecodedTypes.IMyDecoded input, OpcodeSettings settings = OpcodeSettings.NONE) : base("DEC", input, settings) { }
public And(DecodedTypes.IMyDecoded input, OpcodeSettings settings = OpcodeSettings.NONE) : base("AND", input, settings) { }
public Ret(DecodedTypes.IMyDecoded input, OpcodeSettings settings = OpcodeSettings.NONE) : base("RET", input, settings, RegisterCapacity.WORD) { }
public Sub(DecodedTypes.IMyDecoded input, OpcodeSettings settings = OpcodeSettings.NONE, bool useBorrow = false) : base((useBorrow) ? "SBB" : "SUB", input, settings) { // Whether the carry flag will be used as a borrow. UseBorrow = useBorrow; }
public Rxl(DecodedTypes.IMyDecoded input, bool useCarry, OpcodeSettings settings = OpcodeSettings.NONE) : base(useCarry ? "RCL" : "ROL", input, settings) { UseCarry = useCarry; }
public Shl(DecodedTypes.IMyDecoded input, OpcodeSettings settings = OpcodeSettings.NONE) : base("SHL", input, settings) { }
public Add(DecodedTypes.IMyDecoded input, OpcodeSettings settings = OpcodeSettings.NONE, bool useCarry = false) : base((useCarry) ? "ADC" : "ADD", input, settings) { UseCarry = useCarry; }
public Cmp(DecodedTypes.IMyDecoded input, OpcodeSettings settings = OpcodeSettings.NONE) : base("CMP", input, settings) { }
public Test(DecodedTypes.IMyDecoded input, OpcodeSettings settings = OpcodeSettings.NONE) : base("TEST", input, settings) { }
public Sxr(DecodedTypes.IMyDecoded input, bool arithmetic, OpcodeSettings settings = OpcodeSettings.NONE) : base(arithmetic ? "SAR" : "SHR", input, settings) { Arithmetic = arithmetic; }
public Neg(DecodedTypes.IMyDecoded input, OpcodeSettings settings = OpcodeSettings.NONE) : base("NEG", input, settings) { }
public Mov(DecodedTypes.IMyDecoded input, OpcodeSettings settings = OpcodeSettings.NONE) : base("MOV", input, settings) { }
public Set(DecodedTypes.IMyDecoded input, Condition setCondition, OpcodeSettings settings = OpcodeSettings.NONE) : base("SET" + Disassembly.DisassembleCondition(setCondition), input, settings | OpcodeSettings.BYTEMODE) { // Determine the value that will be set. 1 if the condition is true, 0 if false. Result = (byte)(TestCondition(setCondition) ? 1 : 0); }
public Xor(DecodedTypes.IMyDecoded input, OpcodeSettings settings = OpcodeSettings.NONE) : base("XOR", input, settings) { }
public Call(DecodedTypes.IMyDecoded input, OpcodeSettings settings = OpcodeSettings.NONE) : base("CALL", input, settings, input is DecodedTypes.Immediate ? RegisterCapacity.DWORD : RegisterCapacity.QWORD) { }