diff --git a/src/csharp/Intel/Generator/Misc/Python/PyClass.cs b/src/csharp/Intel/Generator/Misc/Python/PyClass.cs index c3343e9f4..71e4fbce2 100644 --- a/src/csharp/Intel/Generator/Misc/Python/PyClass.cs +++ b/src/csharp/Intel/Generator/Misc/Python/PyClass.cs @@ -41,6 +41,7 @@ namespace Generator.Misc.Python { Args, } + [DebuggerDisplay("Count = {Attributes.Count}")] sealed class RustAttributes { public readonly List Attributes = new List(); @@ -71,6 +72,7 @@ namespace Generator.Misc.Python { Args, Raises, Returns, + Note, TestCode, TestOutput, } @@ -132,6 +134,11 @@ namespace Generator.Misc.Python { public ReturnsDocCommentSection(TypeAndDocs returns) => Returns = returns; } + sealed class NoteDocCommentSection : DocCommentSection { + public readonly string[] Lines; + public NoteDocCommentSection(string[] lines) => Lines = lines; + } + sealed class TestCodeDocCommentSection : DocCommentSection { public readonly string[] Lines; public TestCodeDocCommentSection(string[] lines) => Lines = lines; diff --git a/src/csharp/Intel/Generator/Misc/Python/PyClassParser.cs b/src/csharp/Intel/Generator/Misc/Python/PyClassParser.cs index cf0a15e48..44778e7f0 100644 --- a/src/csharp/Intel/Generator/Misc/Python/PyClassParser.cs +++ b/src/csharp/Intel/Generator/Misc/Python/PyClassParser.cs @@ -713,6 +713,7 @@ namespace Generator.Misc.Python { "Args:" => DocCommentKind.Args, "Raises:" => DocCommentKind.Raises, "Returns:" => DocCommentKind.Returns, + "Note:" => DocCommentKind.Note, ".. testcode::" => DocCommentKind.TestCode, ".. testoutput::" => DocCommentKind.TestOutput, _ => DocCommentKind.Text, @@ -790,6 +791,12 @@ namespace Generator.Misc.Python { docs.Sections.Add(new ReturnsDocCommentSection(returns.Value)); break; + case DocCommentKind.Note: + if (!TryGetDescLines(lines, ref i, out descLines, out error)) + return false; + docs.Sections.Add(new NoteDocCommentSection(descLines.ToArray())); + break; + case DocCommentKind.TestCode: if (!TryReadExampleLines(lines, ref i, out var exampleLines, out error)) return false; diff --git a/src/csharp/Intel/Generator/Misc/Python/PyiDocGen.cs b/src/csharp/Intel/Generator/Misc/Python/PyiDocGen.cs new file mode 100644 index 000000000..c55fc330f --- /dev/null +++ b/src/csharp/Intel/Generator/Misc/Python/PyiDocGen.cs @@ -0,0 +1,247 @@ +/* +Copyright (C) 2018-2019 de4dot@gmail.com + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using System.Text; + +namespace Generator.Misc.Python { + // The docs in the *.rs files are in a format understood by sphinx but it's not + // supported by most Python language servers. This class converts the docs to + // something that is accepted by most Python language servers. + // + // Tested: VSCode(Jedi, Pylance, Microsoft) + sealed class PyiDocGen { + readonly List converted = new List(); + + const string HeaderPrefix = "###"; + + public List Convert(DocComments docComments) { + converted.Clear(); + + bool addEmptyLine = false; + var colDefs = new List<(int start, int length)>(); + var tableLines = new List>(); + var columnLengths = new List(); + var sb = new StringBuilder(); + foreach (var section in docComments.Sections) { + if (addEmptyLine) + converted.Add(string.Empty); + addEmptyLine = true; + + switch (section) { + case TextDocCommentSection text: + for (int i = 0; i < text.Lines.Length; i++) { + var line = text.Lines[i]; + + // Convert tables to code blocks. They're not converted to + // markdown tables because Jedi doesn't support tables in + // tooltips. Instead, we create a text block that will be + // rendered with a mono spaced font. + if (IsTableLine(line)) { + GetColumnDefs(colDefs, line); + if (colDefs.Count < 2) + throw new InvalidOperationException($"Invalid table, expected at least 2 columns. First line: {line}"); + + i++; + if (!TryGetNextTableLine(text.Lines, ref i, out var tblLine) || IsTableLine(tblLine)) + throw new InvalidOperationException("Invalid table"); + tableLines.Add(GetColumns(colDefs, tblLine)); + if (!TryGetNextTableLine(text.Lines, ref i, out tblLine) || !IsTableLine(tblLine)) + throw new InvalidOperationException("Invalid table"); + while (TryGetNextTableLine(text.Lines, ref i, out tblLine) && !IsTableLine(tblLine)) + tableLines.Add(GetColumns(colDefs, tblLine)); + + foreach (var tableCols in tableLines) { + for (int j = 0; j < tableCols.Count; j++) + tableCols[j] = FixTableColumn(tableCols[j], j == 0); + } + + columnLengths.Clear(); + for (int j = 0; j < colDefs.Count; j++) + columnLengths.Add(0); + foreach (var tableCols in tableLines) { + if (tableCols.Count != columnLengths.Count) + throw new InvalidOperationException(); + for (int j = 0; j < columnLengths.Count; j++) + columnLengths[j] = Math.Max(columnLengths[j], tableCols[j].Length); + } + const int colSepLen = 2; + for (int j = 0; j < columnLengths.Count - 1; j++) + columnLengths[j] += colSepLen; + + converted.Add("```text"); + for (int j = 0; j < tableLines.Count; j++) { + var tableCols = tableLines[j]; + sb.Clear(); + for (int k = 0; k < tableCols.Count; k++) { + var col = tableCols[k]; + sb.Append(FixCodeBlockLine(col)); + int colLen = columnLengths[k]; + if (col.Length > colLen) + throw new InvalidOperationException(); + if (k + 1 != tableCols.Count) + sb.Append(' ', colLen - col.Length); + } + converted.Add(sb.ToString()); + if (j == 0) { + sb.Clear(); + sb.Append('-', columnLengths.Sum() - columnLengths[^1] + tableLines[0][^1].Length); + converted.Add(sb.ToString()); + } + } + converted.Add("```"); + } + else + converted.Add(FixDocLine(line)); + } + break; + + case ArgsDocCommentSection args: + converted.Add($"{HeaderPrefix} Args:"); + converted.Add(string.Empty); + foreach (var arg in args.Args) + converted.Add(FixDocLine($"- `{arg.Name}` ({arg.SphinxType}): {arg.Documentation}")); + break; + + case RaisesDocCommentSection raises: + converted.Add($"{HeaderPrefix} Raises:"); + converted.Add(string.Empty); + foreach (var raise in raises.Raises) + converted.Add(FixDocLine($"- {raise.SphinxType}: {raise.Documentation}")); + break; + + case ReturnsDocCommentSection returns: + converted.Add($"{HeaderPrefix} Returns:"); + converted.Add(string.Empty); + converted.Add(FixDocLine($"- {returns.Returns.SphinxType}: {returns.Returns.Documentation}")); + break; + + case NoteDocCommentSection note: + converted.Add($"{HeaderPrefix} Note:"); + converted.Add(string.Empty); + foreach (var line in note.Lines) + converted.Add(FixDocLine($"- {line}")); + break; + + case TestCodeDocCommentSection testCode: + converted.Add("```python"); + foreach (var line in testCode.Lines) + converted.Add(FixCodeBlockLine(line)); + converted.Add("```"); + break; + + case TestOutputDocCommentSection testOutput: + converted.Add("```text"); + foreach (var line in testOutput.Lines) + converted.Add(FixCodeBlockLine(line)); + converted.Add("```"); + break; + + default: + throw new InvalidOperationException(); + } + } + + return converted; + } + + static bool IsTableLine(string line) => + line.StartsWith("===", StringComparison.Ordinal) && + line.EndsWith("===", StringComparison.Ordinal); + + static bool TryGetNextTableLine(string[] strings, ref int i, [NotNullWhen(true)] out string? tblLine) { + if (i >= strings.Length) { + tblLine = null; + return false; + } + else { + tblLine = strings[i]; + i++; + return true; + } + } + + static List GetColumns(List<(int start, int length)> colDefs, string line) { + var cols = new List(); + for (int i = 0; i < colDefs.Count; i++) { + bool isLastCol = i + 1 == colDefs.Count; + var colDef = colDefs[i]; + if (colDef.start > 0 && line[colDef.start - 1] != ' ') + throw new InvalidOperationException($"Invalid column #{i}, line: {line}"); + if (!isLastCol && + colDef.start + colDef.length < line.Length && line[colDef.start + colDef.length] != ' ') { + throw new InvalidOperationException($"Invalid column #{i}, line: {line}"); + } + string col; + if (isLastCol) + col = line.Substring(colDef.start).Trim(); + else + col = line.Substring(colDef.start, colDef.length).Trim(); + cols.Add(col); + } + return cols; + } + + static void GetColumnDefs(List<(int start, int length)> colDefs, string line) { + colDefs.Clear(); + for (int index = 0; ;) { + while (index < line.Length && line[index] == ' ') + index++; + if (index >= line.Length) + break; + int startIndex = index; + index = line.IndexOf(' ', index); + if (index < 0) + index = line.Length; + colDefs.Add((startIndex, index - startIndex)); + } + } + + static string FixDocLine(string line) { + line = line.Replace(@"\", @"\\"); + line = line.Replace("\"\"\"", "\\\"\\\"\\\""); + line = line.Replace(@"``", @"`"); + line = line.Replace(@":class:", string.Empty); + if (line == "Examples:") + line = HeaderPrefix + " " + line; + return line; + } + + static string FixCodeBlockLine(string line) { + line = line.Replace(@"\", @"\\"); + line = line.Replace("\"\"\"", "\\\"\\\"\\\""); + return line; + } + + static string FixTableColumn(string line, bool isFirst) { + if (isFirst && line == @"\") + line = string.Empty; + line = line.Replace(@"``", @"`"); + line = line.Replace(@":class:", string.Empty); + return line; + } + } +} diff --git a/src/csharp/Intel/Generator/Misc/Python/PyiGen.cs b/src/csharp/Intel/Generator/Misc/Python/PyiGen.cs index 3c508c285..ceba1fcd3 100644 --- a/src/csharp/Intel/Generator/Misc/Python/PyiGen.cs +++ b/src/csharp/Intel/Generator/Misc/Python/PyiGen.cs @@ -169,26 +169,29 @@ namespace Generator.Misc.Python { writer.WriteLine($"class {pythonName}({baseClass}): ..."); } + var docGen = new PyiDocGen(); foreach (var classStr in classOrder) { var pyClass = toClass[classStr]; toClass.Remove(classStr); writer.WriteLine(); writer.WriteLine($"class {idConverter.Type(pyClass.Name)}:"); using (writer.Indent()) { + WriteDocs(writer, docGen.Convert(pyClass.DocComments)); + int defCount = 0; foreach (var member in GetMembers(pyClass)) { switch (member) { case PyMethod method: var docComments = method.Attributes.Any(AttributeKind.New) == true ? pyClass.DocComments : method.DocComments; - Write(writer, idConverter, pyClass, method, docComments, toEnumType); + Write(writer, docGen, idConverter, pyClass, method, docComments, toEnumType); defCount++; break; case PyProperty property: - Write(writer, idConverter, pyClass, property.Getter, property.Getter.DocComments, toEnumType); + Write(writer, docGen, idConverter, pyClass, property.Getter, property.Getter.DocComments, toEnumType); defCount++; if (property.Setter is not null) { - Write(writer, idConverter, pyClass, property.Setter, property.Getter.DocComments, toEnumType); + Write(writer, docGen, idConverter, pyClass, property.Setter, property.Getter.DocComments, toEnumType); defCount++; } break; @@ -205,7 +208,26 @@ namespace Generator.Misc.Python { } } - static void Write(FileWriter writer, IdentifierConverter idConverter, PyClass pyClass, PyMethod method, DocComments docComments, Dictionary toEnumType) { + static void WriteDocs(FileWriter writer, List docs) { + if (docs.Count == 0) + throw new InvalidOperationException(); + + const string docQuotes = "\"\"\""; + if (docs.Count == 1) + writer.WriteLine($"{docQuotes}{docs[0]}{docQuotes}"); + else { + writer.WriteLine(docQuotes); + foreach (var doc in docs) { + if (doc == string.Empty) + writer.WriteLineNoIndent(string.Empty); + else + writer.WriteLine(doc); + } + writer.WriteLine(docQuotes); + } + } + + static void Write(FileWriter writer, PyiDocGen docGen, IdentifierConverter idConverter, PyClass pyClass, PyMethod method, DocComments docComments, Dictionary toEnumType) { if (method.Attributes.Any(AttributeKind.ClassMethod) == true) writer.WriteLine("@classmethod"); if (method.Attributes.Any(AttributeKind.StaticMethod) == true) @@ -291,7 +313,15 @@ namespace Generator.Misc.Python { writer.Write(GetReturnType(pyClass, method.Name, method.RustReturnType, sphinxReturnType)); else writer.Write("None"); - writer.WriteLine(": ..."); + if (method.DocComments.Sections.Count == 0) + writer.WriteLine(": ..."); + else { + writer.WriteLine(":"); + using (writer.Indent()) { + WriteDocs(writer, docGen.Convert(method.DocComments)); + writer.WriteLine("..."); + } + } } static bool TryGetValueStr(IdentifierConverter idConverter, string typeStr, string defaultValueStr, Dictionary toEnumType, [NotNullWhen(true)] out string? valueStr) { @@ -395,7 +425,7 @@ namespace Generator.Misc.Python { } } - IEnumerable GetMembers(PyClass pyClass) { + static IEnumerable GetMembers(PyClass pyClass) { var setters = pyClass.Methods.Where(a => a.Attributes.Any(AttributeKind.Setter) == true).ToDictionary(a => a.Name, a => a, StringComparer.Ordinal); foreach (var method in pyClass.Methods) { if (method.Attributes.Any(AttributeKind.Setter) == true) diff --git a/src/rust/iced-x86-py/src/iced_x86/_iced_x86_py.pyi b/src/rust/iced-x86-py/src/iced_x86/_iced_x86_py.pyi index a4a1fedaf..ff6abc529 100644 --- a/src/rust/iced-x86-py/src/iced_x86/_iced_x86_py.pyi +++ b/src/rust/iced-x86-py/src/iced_x86/_iced_x86_py.pyi @@ -72,228 +72,602 @@ class RoundingControl(IntEnum): ... class TupleType(IntEnum): ... class OpCodeInfo: + """ + Opcode info, returned by `Instruction.op_code` or created by the constructor + + ### Args: + + - `code` (`Code`): Code value + + ### Examples: + + ```python + from iced_x86 import * + + op_code = OpCodeInfo(Code.EVEX_VMOVAPD_YMM_K1Z_YMMM256) + assert op_code.op_code_string == "EVEX.256.66.0F.W1 28 /r" + assert op_code.encoding == EncodingKind.EVEX + assert OpCodeInfo(Code.SUB_R8_RM8).op_code == 0x2A + assert OpCodeInfo(Code.CVTPI2PS_XMM_MMM64).op_code == 0x2A + ``` + """ def __init__(self, code: Code) -> None: ... @property - def code(self) -> Code: ... + def code(self) -> Code: + """ + `Code`: Gets the code (a `Code` enum value) + + ### Examples: + + ```python + from iced_x86 import * + + op_code = OpCodeInfo(Code.EVEX_VMOVAPD_YMM_K1Z_YMMM256) + assert op_code.code == Code.EVEX_VMOVAPD_YMM_K1Z_YMMM256 + ``` + """ + ... + @property + def mnemonic(self) -> Mnemonic: + """ + `Mnemonic`: Gets the mnemonic (a `Mnemonic` enum value) + + ### Examples: + + ```python + from iced_x86 import * + + op_code = OpCodeInfo(Code.EVEX_VMOVAPD_YMM_K1Z_YMMM256) + assert op_code.mnemonic == Mnemonic.VMOVAPD + ``` + """ + ... + @property + def encoding(self) -> EncodingKind: + """ + `EncodingKind`: Gets the encoding (an `EncodingKind` enum value) + + ### Examples: + + ```python + from iced_x86 import * + + op_code = OpCodeInfo(Code.EVEX_VMOVAPD_YMM_K1Z_YMMM256) + assert op_code.encoding == EncodingKind.EVEX + ``` + """ + ... + @property + def is_instruction(self) -> bool: + """ + bool: `True` if it's an instruction, `False` if it's eg. `Code.INVALID`, `db`, `dw`, `dd`, `dq` + + ### Examples: + + ```python + from iced_x86 import * + + assert OpCodeInfo(Code.EVEX_VMOVAPD_YMM_K1Z_YMMM256).is_instruction + assert not OpCodeInfo(Code.INVALID).is_instruction + assert not OpCodeInfo(Code.DECLAREBYTE).is_instruction + ``` + """ + ... + @property + def mode16(self) -> bool: + """bool: `True` if it's an instruction available in 16-bit mode""" + ... + @property + def mode32(self) -> bool: + """bool: `True` if it's an instruction available in 32-bit mode""" + ... + @property + def mode64(self) -> bool: + """bool: `True` if it's an instruction available in 64-bit mode""" + ... + @property + def fwait(self) -> bool: + """bool: `True` if an `FWAIT` (`9B`) instruction is added before the instruction""" + ... + @property + def operand_size(self) -> int: + """int: (`u8`) (Legacy encoding) Gets the required operand size (16,32,64) or 0""" + ... + @property + def address_size(self) -> int: + """int: (`u8`) (Legacy encoding) Gets the required address size (16,32,64) or 0""" + ... + @property + def l(self) -> int: + """int: (`u8`) (VEX/XOP/EVEX) `L` / `L'L` value or default value if `OpCodeInfo.is_lig` is `True`""" + ... + @property + def w(self) -> int: + """int: (`u8`) (VEX/XOP/EVEX) `W` value or default value if `OpCodeInfo.is_wig` or `OpCodeInfo.is_wig32` is `True`""" + ... + @property + def is_lig(self) -> bool: + """ + bool: (VEX/XOP/EVEX) `True` if the `L` / `L'L` fields are ignored. + + EVEX: if reg-only ops and `{er}` (`EVEX.b` is set), `L'L` is the rounding control and not ignored. + """ + ... + @property + def is_wig(self) -> bool: + """bool: (VEX/XOP/EVEX) `True` if the `W` field is ignored in 16/32/64-bit modes""" + ... + @property + def is_wig32(self) -> bool: + """bool: (VEX/XOP/EVEX) `True` if the `W` field is ignored in 16/32-bit modes (but not 64-bit mode)""" + ... + @property + def tuple_type(self) -> TupleType: + """`TupleType`: (EVEX) Gets the tuple type (a `TupleType` enum value)""" + ... + @property + def memory_size(self) -> MemorySize: + """`MemorySize`: If it has a memory operand, gets the `MemorySize` (non-broadcast memory type)""" + ... + @property + def broadcast_memory_size(self) -> MemorySize: + """`MemorySize`: If it has a memory operand, gets the `MemorySize` (broadcast memory type)""" + ... + @property + def can_broadcast(self) -> bool: + """bool: (EVEX) `True` if the instruction supports broadcasting (`EVEX.b` bit) (if it has a memory operand)""" + ... + @property + def can_use_rounding_control(self) -> bool: + """bool: (EVEX) `True` if the instruction supports rounding control""" + ... + @property + def can_suppress_all_exceptions(self) -> bool: + """bool: (EVEX) `True` if the instruction supports suppress all exceptions""" + ... + @property + def can_use_op_mask_register(self) -> bool: + """bool: (EVEX) `True` if an op mask register can be used""" + ... + @property + def require_op_mask_register(self) -> bool: + """bool: (EVEX) `True` if a non-zero op mask register must be used""" + ... + @property + def can_use_zeroing_masking(self) -> bool: + """bool: (EVEX) `True` if the instruction supports zeroing masking (if one of the op mask registers `K1`-`K7` is used and destination operand is not a memory operand)""" + ... + @property + def can_use_lock_prefix(self) -> bool: + """bool: `True` if the `LOCK` (`F0`) prefix can be used""" + ... + @property + def can_use_xacquire_prefix(self) -> bool: + """bool: `True` if the `XACQUIRE` (`F2`) prefix can be used""" + ... + @property + def can_use_xrelease_prefix(self) -> bool: + """bool: `True` if the `XRELEASE` (`F3`) prefix can be used""" + ... + @property + def can_use_rep_prefix(self) -> bool: + """bool: `True` if the `REP` / `REPE` (`F3`) prefixes can be used""" + ... @property - def mnemonic(self) -> Mnemonic: ... + def can_use_repne_prefix(self) -> bool: + """bool: `True` if the `REPNE` (`F2`) prefix can be used""" + ... @property - def encoding(self) -> EncodingKind: ... + def can_use_bnd_prefix(self) -> bool: + """bool: `True` if the `BND` (`F2`) prefix can be used""" + ... + @property + def can_use_hint_taken_prefix(self) -> bool: + """bool: `True` if the `HINT-TAKEN` (`3E`) and `HINT-NOT-TAKEN` (`2E`) prefixes can be used""" + ... + @property + def can_use_notrack_prefix(self) -> bool: + """bool: `True` if the `NOTRACK` (`3E`) prefix can be used""" + ... + @property + def ignores_rounding_control(self) -> bool: + """bool: `True` if rounding control is ignored (#UD is not generated)""" + ... + @property + def amd_lock_reg_bit(self) -> bool: + """bool: `True` if the `LOCK` prefix can be used as an extra register bit (bit 3) to access registers 8-15 without a `REX` prefix (eg. in 32-bit mode)""" + ... + @property + def default_op_size64(self) -> bool: + """bool: `True` if the default operand size is 64 in 64-bit mode. A `66` prefix can switch to 16-bit operand size.""" + ... + @property + def force_op_size64(self) -> bool: + """bool: `True` if the operand size is always 64 in 64-bit mode. A `66` prefix is ignored.""" + ... + @property + def intel_force_op_size64(self) -> bool: + """bool: `True` if the Intel decoder forces 64-bit operand size. A `66` prefix is ignored.""" + ... + @property + def must_be_cpl0(self) -> bool: + """bool: `True` if it can only be executed when CPL=0""" + ... @property - def is_instruction(self) -> bool: ... + def cpl0(self) -> bool: + """bool: `True` if it can be executed when CPL=0""" + ... @property - def mode16(self) -> bool: ... + def cpl1(self) -> bool: + """bool: `True` if it can be executed when CPL=1""" + ... @property - def mode32(self) -> bool: ... + def cpl2(self) -> bool: + """bool: `True` if it can be executed when CPL=2""" + ... @property - def mode64(self) -> bool: ... + def cpl3(self) -> bool: + """bool: `True` if it can be executed when CPL=3""" + ... @property - def fwait(self) -> bool: ... + def is_input_output(self) -> bool: + """bool: `True` if the instruction accesses the I/O address space (eg. `IN`, `OUT`, `INS`, `OUTS`)""" + ... @property - def operand_size(self) -> int: ... + def is_nop(self) -> bool: + """bool: `True` if it's one of the many nop instructions (does not include FPU nop instructions, eg. `FNOP`)""" + ... @property - def address_size(self) -> int: ... + def is_reserved_nop(self) -> bool: + """bool: `True` if it's one of the many reserved nop instructions (eg. `0F0D`, `0F18-0F1F`)""" + ... @property - def l(self) -> int: ... + def is_serializing_intel(self) -> bool: + """bool: `True` if it's a serializing instruction (Intel CPUs)""" + ... @property - def w(self) -> int: ... + def is_serializing_amd(self) -> bool: + """bool: `True` if it's a serializing instruction (AMD CPUs)""" + ... @property - def is_lig(self) -> bool: ... + def may_require_cpl0(self) -> bool: + """bool: `True` if the instruction requires either CPL=0 or CPL<=3 depending on some CPU option (eg. `CR4.TSD`, `CR4.PCE`, `CR4.UMIP`)""" + ... @property - def is_wig(self) -> bool: ... + def is_cet_tracked(self) -> bool: + """bool: `True` if it's a tracked `JMP`/`CALL` indirect instruction (CET)""" + ... @property - def is_wig32(self) -> bool: ... + def is_non_temporal(self) -> bool: + """bool: `True` if it's a non-temporal hint memory access (eg. `MOVNTDQ`)""" + ... @property - def tuple_type(self) -> TupleType: ... + def is_fpu_no_wait(self) -> bool: + """bool: `True` if it's a no-wait FPU instruction, eg. `FNINIT`""" + ... @property - def memory_size(self) -> MemorySize: ... + def ignores_mod_bits(self) -> bool: + """bool: `True` if the mod bits are ignored and it's assumed `modrm[7:6] == 11b`""" + ... @property - def broadcast_memory_size(self) -> MemorySize: ... + def no66(self) -> bool: + """bool: `True` if the `66` prefix is not allowed (it will #UD)""" + ... @property - def can_broadcast(self) -> bool: ... + def nfx(self) -> bool: + """bool: `True` if the `F2`/`F3` prefixes aren't allowed""" + ... @property - def can_use_rounding_control(self) -> bool: ... + def requires_unique_reg_nums(self) -> bool: + """ + bool: `True` if the index reg's reg-num (vsib op) (if any) and register ops' reg-nums must be unique, + eg. `MNEMONIC XMM1,YMM1,[RAX+ZMM1*2]` is invalid. Registers = `XMM`/`YMM`/`ZMM`/`TMM`. + """ + ... @property - def can_suppress_all_exceptions(self) -> bool: ... + def is_privileged(self) -> bool: + """bool: `True` if it's a privileged instruction (all CPL=0 instructions (except `VMCALL`) and IOPL instructions `IN`, `INS`, `OUT`, `OUTS`, `CLI`, `STI`)""" + ... @property - def can_use_op_mask_register(self) -> bool: ... + def is_save_restore(self) -> bool: + """bool: `True` if it reads/writes too many registers""" + ... @property - def require_op_mask_register(self) -> bool: ... + def is_stack_instruction(self) -> bool: + """bool: `True` if it's an instruction that implicitly uses the stack register, eg. `CALL`, `POP`, etc""" + ... @property - def can_use_zeroing_masking(self) -> bool: ... + def ignores_segment(self) -> bool: + """bool: `True` if the instruction doesn't read the segment register if it uses a memory operand""" + ... @property - def can_use_lock_prefix(self) -> bool: ... + def is_op_mask_read_write(self) -> bool: + """bool: `True` if the op mask register is read and written (instead of just read). This also implies that it can't be `K0`.""" + ... @property - def can_use_xacquire_prefix(self) -> bool: ... + def real_mode(self) -> bool: + """bool: `True` if it can be executed in real mode""" + ... @property - def can_use_xrelease_prefix(self) -> bool: ... + def protected_mode(self) -> bool: + """bool: `True` if it can be executed in protected mode""" + ... @property - def can_use_rep_prefix(self) -> bool: ... + def virtual8086_mode(self) -> bool: + """bool: `True` if it can be executed in virtual 8086 mode""" + ... @property - def can_use_repne_prefix(self) -> bool: ... + def compatibility_mode(self) -> bool: + """bool: `True` if it can be executed in compatibility mode""" + ... @property - def can_use_bnd_prefix(self) -> bool: ... + def long_mode(self) -> bool: + """bool: `True` if it can be executed in 64-bit mode""" + ... @property - def can_use_hint_taken_prefix(self) -> bool: ... + def use_outside_smm(self) -> bool: + """bool: `True` if it can be used outside SMM""" + ... @property - def can_use_notrack_prefix(self) -> bool: ... + def use_in_smm(self) -> bool: + """bool: `True` if it can be used in SMM""" + ... @property - def ignores_rounding_control(self) -> bool: ... + def use_outside_enclave_sgx(self) -> bool: + """bool: `True` if it can be used outside an enclave (SGX)""" + ... @property - def amd_lock_reg_bit(self) -> bool: ... + def use_in_enclave_sgx1(self) -> bool: + """bool: `True` if it can be used inside an enclave (SGX1)""" + ... @property - def default_op_size64(self) -> bool: ... + def use_in_enclave_sgx2(self) -> bool: + """bool: `True` if it can be used inside an enclave (SGX2)""" + ... @property - def force_op_size64(self) -> bool: ... - @property - def intel_force_op_size64(self) -> bool: ... - @property - def must_be_cpl0(self) -> bool: ... - @property - def cpl0(self) -> bool: ... - @property - def cpl1(self) -> bool: ... - @property - def cpl2(self) -> bool: ... - @property - def cpl3(self) -> bool: ... - @property - def is_input_output(self) -> bool: ... - @property - def is_nop(self) -> bool: ... - @property - def is_reserved_nop(self) -> bool: ... - @property - def is_serializing_intel(self) -> bool: ... - @property - def is_serializing_amd(self) -> bool: ... - @property - def may_require_cpl0(self) -> bool: ... - @property - def is_cet_tracked(self) -> bool: ... - @property - def is_non_temporal(self) -> bool: ... - @property - def is_fpu_no_wait(self) -> bool: ... - @property - def ignores_mod_bits(self) -> bool: ... - @property - def no66(self) -> bool: ... - @property - def nfx(self) -> bool: ... - @property - def requires_unique_reg_nums(self) -> bool: ... - @property - def is_privileged(self) -> bool: ... - @property - def is_save_restore(self) -> bool: ... - @property - def is_stack_instruction(self) -> bool: ... - @property - def ignores_segment(self) -> bool: ... - @property - def is_op_mask_read_write(self) -> bool: ... - @property - def real_mode(self) -> bool: ... - @property - def protected_mode(self) -> bool: ... - @property - def virtual8086_mode(self) -> bool: ... - @property - def compatibility_mode(self) -> bool: ... - @property - def long_mode(self) -> bool: ... - @property - def use_outside_smm(self) -> bool: ... - @property - def use_in_smm(self) -> bool: ... - @property - def use_outside_enclave_sgx(self) -> bool: ... - @property - def use_in_enclave_sgx1(self) -> bool: ... - @property - def use_in_enclave_sgx2(self) -> bool: ... - @property - def use_outside_vmx_op(self) -> bool: ... - @property - def use_in_vmx_root_op(self) -> bool: ... - @property - def use_in_vmx_non_root_op(self) -> bool: ... - @property - def use_outside_seam(self) -> bool: ... - @property - def use_in_seam(self) -> bool: ... - @property - def tdx_non_root_gen_ud(self) -> bool: ... - @property - def tdx_non_root_gen_ve(self) -> bool: ... - @property - def tdx_non_root_may_gen_ex(self) -> bool: ... - @property - def intel_vm_exit(self) -> bool: ... - @property - def intel_may_vm_exit(self) -> bool: ... - @property - def intel_smm_vm_exit(self) -> bool: ... - @property - def amd_vm_exit(self) -> bool: ... - @property - def amd_may_vm_exit(self) -> bool: ... - @property - def tsx_abort(self) -> bool: ... - @property - def tsx_impl_abort(self) -> bool: ... - @property - def tsx_may_abort(self) -> bool: ... - @property - def intel_decoder16(self) -> bool: ... - @property - def intel_decoder32(self) -> bool: ... - @property - def intel_decoder64(self) -> bool: ... - @property - def amd_decoder16(self) -> bool: ... - @property - def amd_decoder32(self) -> bool: ... - @property - def amd_decoder64(self) -> bool: ... - @property - def decoder_option(self) -> DecoderOptions: ... - @property - def table(self) -> OpCodeTableKind: ... - @property - def mandatory_prefix(self) -> MandatoryPrefix: ... - @property - def op_code(self) -> int: ... - @property - def op_code_len(self) -> int: ... - @property - def is_group(self) -> bool: ... - @property - def group_index(self) -> int: ... - @property - def is_rm_group(self) -> bool: ... - @property - def rm_group_index(self) -> int: ... - @property - def op_count(self) -> int: ... - @property - def op0_kind(self) -> OpCodeOperandKind: ... - @property - def op1_kind(self) -> OpCodeOperandKind: ... - @property - def op2_kind(self) -> OpCodeOperandKind: ... - @property - def op3_kind(self) -> OpCodeOperandKind: ... - @property - def op4_kind(self) -> OpCodeOperandKind: ... - def op_kind(self, operand: int) -> OpCodeOperandKind: ... - def op_kinds(self) -> List[OpCodeOperandKind]: ... - def is_available_in_mode(self, bitness: int) -> bool: ... - @property - def op_code_string(self) -> str: ... - @property - def instruction_string(self) -> str: ... + def use_outside_vmx_op(self) -> bool: + """bool: `True` if it can be used outside VMX operation""" + ... + @property + def use_in_vmx_root_op(self) -> bool: + """bool: `True` if it can be used in VMX root operation""" + ... + @property + def use_in_vmx_non_root_op(self) -> bool: + """bool: `True` if it can be used in VMX non-root operation""" + ... + @property + def use_outside_seam(self) -> bool: + """bool: `True` if it can be used outside SEAM""" + ... + @property + def use_in_seam(self) -> bool: + """bool: `True` if it can be used in SEAM""" + ... + @property + def tdx_non_root_gen_ud(self) -> bool: + """bool: `True` if #UD is generated in TDX non-root operation""" + ... + @property + def tdx_non_root_gen_ve(self) -> bool: + """bool: `True` if #VE is generated in TDX non-root operation""" + ... + @property + def tdx_non_root_may_gen_ex(self) -> bool: + """bool: `True` if an exception (eg. #GP(0), #VE) may be generated in TDX non-root operation""" + ... + @property + def intel_vm_exit(self) -> bool: + """bool: (Intel VMX) `True` if it causes a VM exit in VMX non-root operation""" + ... + @property + def intel_may_vm_exit(self) -> bool: + """bool: (Intel VMX) `True` if it may cause a VM exit in VMX non-root operation""" + ... + @property + def intel_smm_vm_exit(self) -> bool: + """bool: (Intel VMX) `True` if it causes an SMM VM exit in VMX root operation (if dual-monitor treatment is activated)""" + ... + @property + def amd_vm_exit(self) -> bool: + """bool: (AMD SVM) `True` if it causes a #VMEXIT in guest mode""" + ... + @property + def amd_may_vm_exit(self) -> bool: + """bool: (AMD SVM) `True` if it may cause a #VMEXIT in guest mode""" + ... + @property + def tsx_abort(self) -> bool: + """bool: `True` if it causes a TSX abort inside a TSX transaction""" + ... + @property + def tsx_impl_abort(self) -> bool: + """bool: `True` if it causes a TSX abort inside a TSX transaction depending on the implementation""" + ... + @property + def tsx_may_abort(self) -> bool: + """bool: `True` if it may cause a TSX abort inside a TSX transaction depending on some condition""" + ... + @property + def intel_decoder16(self) -> bool: + """bool: `True` if it's decoded by iced's 16-bit Intel decoder""" + ... + @property + def intel_decoder32(self) -> bool: + """bool: `True` if it's decoded by iced's 32-bit Intel decoder""" + ... + @property + def intel_decoder64(self) -> bool: + """bool: `True` if it's decoded by iced's 64-bit Intel decoder""" + ... + @property + def amd_decoder16(self) -> bool: + """bool: `True` if it's decoded by iced's 16-bit AMD decoder""" + ... + @property + def amd_decoder32(self) -> bool: + """bool: `True` if it's decoded by iced's 32-bit AMD decoder""" + ... + @property + def amd_decoder64(self) -> bool: + """bool: `True` if it's decoded by iced's 64-bit AMD decoder""" + ... + @property + def decoder_option(self) -> DecoderOptions: + """`DecoderOptions`: Gets the decoder option that's needed to decode the instruction or `DecoderOptions.NONE`.""" + ... + @property + def table(self) -> OpCodeTableKind: + """`OpCodeTableKind`: Gets the opcode table (a `OpCodeTableKind` enum value)""" + ... + @property + def mandatory_prefix(self) -> MandatoryPrefix: + """`MandatoryPrefix`: Gets the mandatory prefix (a `MandatoryPrefix` enum value)""" + ... + @property + def op_code(self) -> int: + """ + int: (`u32`) Gets the opcode byte(s). The low byte(s) of this value is the opcode. The length is in `OpCodeInfo.op_code_len`. + It doesn't include the table value, see `OpCodeInfo.table`. + + ### Examples: + + ```python + from iced_x86 import * + + assert OpCodeInfo(Code.FFREEP_STI).op_code == 0xDFC0 + assert OpCodeInfo(Code.VMRUNW).op_code == 0x01D8 + assert OpCodeInfo(Code.SUB_R8_RM8).op_code == 0x2A + assert OpCodeInfo(Code.CVTPI2PS_XMM_MMM64).op_code == 0x2A + ``` + """ + ... + @property + def op_code_len(self) -> int: + """ + int: (`u8`) Gets the length of the opcode bytes (`OpCodeInfo.op_code`). The low bytes is the opcode value. + + ### Examples: + + ```python + from iced_x86 import * + + assert OpCodeInfo(Code.FFREEP_STI).op_code_len == 2 + assert OpCodeInfo(Code.VMRUNW).op_code_len == 2 + assert OpCodeInfo(Code.SUB_R8_RM8).op_code_len == 1 + assert OpCodeInfo(Code.CVTPI2PS_XMM_MMM64).op_code_len == 1 + ``` + """ + ... + @property + def is_group(self) -> bool: + """bool: `True` if it's part of a group""" + ... + @property + def group_index(self) -> int: + """int: (`i8`) Group index (0-7) or -1. If it's 0-7, it's stored in the `reg` field of the `modrm` byte.""" + ... + @property + def is_rm_group(self) -> bool: + """bool: `True` if it's part of a modrm.rm group""" + ... + @property + def rm_group_index(self) -> int: + """int: (`i8`) Group index (0-7) or -1. If it's 0-7, it's stored in the `rm` field of the `modrm` byte.""" + ... + @property + def op_count(self) -> int: + """int: (`u8`) Gets the number of operands""" + ... + @property + def op0_kind(self) -> OpCodeOperandKind: + """`OpCodeOperandKind`: Gets operand #0's opkind (a `OpCodeOperandKind` enum value)""" + ... + @property + def op1_kind(self) -> OpCodeOperandKind: + """`OpCodeOperandKind`: Gets operand #1's opkind (a `OpCodeOperandKind` enum value)""" + ... + @property + def op2_kind(self) -> OpCodeOperandKind: + """`OpCodeOperandKind`: Gets operand #2's opkind (a `OpCodeOperandKind` enum value)""" + ... + @property + def op3_kind(self) -> OpCodeOperandKind: + """`OpCodeOperandKind`: Gets operand #3's opkind (a `OpCodeOperandKind` enum value)""" + ... + @property + def op4_kind(self) -> OpCodeOperandKind: + """`OpCodeOperandKind`: Gets operand #4's opkind (a `OpCodeOperandKind` enum value)""" + ... + def op_kind(self, operand: int) -> OpCodeOperandKind: + """ + Gets an operand's opkind (a `OpCodeOperandKind` enum value) + + ### Args: + + - `operand` (int): Operand number, 0-4 + + ### Returns: + + - `OpCodeOperandKind`: Operand kind + + ### Raises: + + - ValueError: If `operand` is invalid + """ + ... + def op_kinds(self) -> List[OpCodeOperandKind]: + """ + Gets all operand kinds (a list of `OpCodeOperandKind` enum values) + + ### Returns: + + - List[OpCodeOperandKind]: All operand kinds + """ + ... + def is_available_in_mode(self, bitness: int) -> bool: + """ + Checks if the instruction is available in 16-bit mode, 32-bit mode or 64-bit mode + + ### Args: + + - `bitness` (int): 16, 32 or 64 + + ### Returns: + + - bool: `True` if it's available in the mode + """ + ... + @property + def op_code_string(self) -> str: + """ + str: Gets the opcode string, eg. `VEX.128.66.0F38.W0 78 /r`, see also `OpCodeInfo.instruction_string` + + ### Examples: + + ```python + from iced_x86 import * + + op_code = OpCodeInfo(Code.EVEX_VMOVAPD_YMM_K1Z_YMMM256) + assert op_code.op_code_string == "EVEX.256.66.0F.W1 28 /r" + ``` + """ + ... + @property + def instruction_string(self) -> str: + """ + str: Gets the instruction string, eg. `VPBROADCASTB xmm1, xmm2/m8`, see also `OpCodeInfo.op_code_string` + + ### Examples: + + ```python + from iced_x86 import * + + op_code = OpCodeInfo(Code.EVEX_VMOVAPD_YMM_K1Z_YMMM256) + assert op_code.instruction_string == "VMOVAPD ymm1 {k1}{z}, ymm2/m256" + ``` + """ + ... def __repr__(self) -> str: ... def __str__(self) -> str: ... def __format__(self, format_spec: str) -> str: ... @@ -302,381 +676,1918 @@ class OpCodeInfo: def __hash__(self) -> int: ... class ConstantOffsets: + """ + Contains the offsets of the displacement and immediate. + + Call `Decoder.get_constant_offsets` or `Encoder.get_constant_offsets` to get the + offsets of the constants after the instruction has been decoded/encoded. + """ @property - def displacement_offset(self) -> int: ... + def displacement_offset(self) -> int: + """int: (`u32`) The offset of the displacement, if any""" + ... @property - def displacement_size(self) -> int: ... + def displacement_size(self) -> int: + """int: (`u32`) Size in bytes of the displacement, or 0 if there's no displacement""" + ... @property - def immediate_offset(self) -> int: ... + def immediate_offset(self) -> int: + """ + int: (`u32`) The offset of the first immediate, if any. + + This field can be invalid even if the operand has an immediate if it's an immediate that isn't part + of the instruction stream, eg. `SHL AL,1`. + """ + ... @property - def immediate_size(self) -> int: ... + def immediate_size(self) -> int: + """int: (`u32`) Size in bytes of the first immediate, or 0 if there's no immediate""" + ... @property - def immediate_offset2(self) -> int: ... + def immediate_offset2(self) -> int: + """int: (`u32`) The offset of the second immediate, if any.""" + ... @property - def immediate_size2(self) -> int: ... + def immediate_size2(self) -> int: + """int: (`u32`) Size in bytes of the second immediate, or 0 if there's no second immediate""" + ... @property - def has_displacement(self) -> bool: ... + def has_displacement(self) -> bool: + """bool: `True` if `ConstantOffsets.displacement_offset` and `ConstantOffsets.displacement_size` are valid""" + ... @property - def has_immediate(self) -> bool: ... + def has_immediate(self) -> bool: + """bool: `True` if `ConstantOffsets.immediate_offset` and `ConstantOffsets.immediate_size` are valid""" + ... @property - def has_immediate2(self) -> bool: ... + def has_immediate2(self) -> bool: + """bool: `True` if `ConstantOffsets.immediate_offset2` and `ConstantOffsets.immediate_size2` are valid""" + ... def __eq__(self, other: Any) -> bool: ... def __ne__(self, other: Any) -> bool: ... def __hash__(self) -> int: ... class FpuStackIncrementInfo: + """ + Contains the FPU `TOP` increment, whether it's conditional and whether the instruction writes to `TOP` + + ### Args: + + - `increment` (int): (`i32`) Used if `writes_top` is `True`. Value added to `TOP`. + - `conditional` (bool): `True` if it's a conditional push/pop (eg. `FPTAN` or `FSINCOS`) + - `writes_top` (bool): `True` if `TOP` is written (it's a conditional/unconditional push/pop, `FNSAVE`, `FLDENV`, etc) + """ def __init__(self, increment: int, conditional: bool, writes_top: bool) -> None: ... @property - def increment(self) -> int: ... + def increment(self) -> int: + """ + int: (`i32`) Used if `FpuStackIncrementInfo.writes_top` is `True`. Value added to `TOP`. + + This is negative if it pushes one or more values and positive if it pops one or more values + and `0` if it writes to `TOP` (eg. `FLDENV`, etc) without pushing/popping anything. + """ + ... @property - def conditional(self) -> bool: ... + def conditional(self) -> bool: + """bool: `True` if it's a conditional push/pop (eg. `FPTAN` or `FSINCOS`)""" + ... @property - def writes_top(self) -> bool: ... + def writes_top(self) -> bool: + """bool: `True` if `TOP` is written (it's a conditional/unconditional push/pop, `FNSAVE`, `FLDENV`, etc)""" + ... class MemoryOperand: + """ + Memory operand passed to one of `Instruction`'s `create*()` constructor methods + + ### Args: + + - `base` (`Register`): (default = `Register.NONE`) Base register or `Register.NONE` + - `index` (`Register`): (default = `Register.NONE`) Index register or `Register.NONE` + - `scale` (int): (default = `1`) Index register scale (1, 2, 4, or 8) + - `displ` (int): (`i32`) (default = `0`) Memory displacement + - `displ_size` (int): (default = `0`) 0 (no displ), 1 (16/32/64-bit, but use 2/4/8 if it doesn't fit in a `i8`), 2 (16-bit), 4 (32-bit) or 8 (64-bit) + - `is_broadcast` (bool): (default = `False`) `True` if it's broadcasted memory (EVEX instructions) + - `seg` (`Register`): (default = `Register.NONE`) Segment override or `Register.NONE` + """ def __init__(self, base: Register = Register.NONE, index: Register = Register.NONE, scale: int = 1, displ: int = 0, displ_size: int = 0, is_broadcast: bool = False, seg: Register = Register.NONE) -> None: ... - def __copy__(self) -> MemoryOperand: ... - def __deepcopy__(self, memo: Any) -> MemoryOperand: ... - def clone(self) -> MemoryOperand: ... + def __copy__(self) -> MemoryOperand: + """ + Returns a copy of this instance. + + ### Returns: + + - MemoryOperand: A copy of this instance + + This is identical to `MemoryOperand.clone` + """ + ... + def __deepcopy__(self, memo: Any) -> MemoryOperand: + """ + Returns a copy of this instance. + + ### Args: + + - `memo` (Any): memo dict + + ### Returns: + + - MemoryOperand: A copy of this instance + + This is identical to `MemoryOperand.clone` + """ + ... + def clone(self) -> MemoryOperand: + """ + Returns a copy of this instance. + + ### Returns: + + - MemoryOperand: A copy of this instance + """ + ... def __eq__(self, other: Any) -> bool: ... def __ne__(self, other: Any) -> bool: ... def __hash__(self) -> int: ... class Instruction: + """ + A 16/32/64-bit x86 instruction. Created by `Decoder` or by `Instruction.create*()` methods. + + ### Examples: + + A decoder is usually used to create instructions: + + ```python + from iced_x86 import * + + # xchg ah,[rdx+rsi+16h] + data = b"\\x86\\x64\\x32\\x16" + decoder = Decoder(64, data) + decoder.ip = 0x1234_5678 + + instr = decoder.decode() + + # Instruction supports __bool__() and returns True if it's + # a valid instruction: + if not instr: + print("Invalid instruction (garbage, data, etc)") + # The above code is the same as: + if instr.code == Code.INVALID: + print("Not an instruction") + ``` + + But there are also static `Instruction.create*()` methods that can be used to create instructions: + + ```python + nop = Instruction.create(Code.NOPD) + xor = Instruction.create_reg_i32(Code.XOR_RM64_IMM8, Register.R14, -1) + rep_stosd = Instruction.create_rep_stosd(64) + add = Instruction.create_mem_i32(Code.ADD_RM64_IMM8, MemoryOperand(Register.RCX, Register.RDX, 8, 0x1234_5678), 2) + print(f"{nop}") + print(f"{xor}") + print(f"{rep_stosd}") + print(f"{add}") + ``` + + Output: + + ```text + nop + xor r14,0FFFFFFFFFFFFFFFFh + rep stosd + add qword ptr [rcx+rdx*8+12345678h],2 + ``` + + Once you have an instruction you can format it either by using a `Formatter` + or by calling the instruction's `__repr__()`, `__str__()` or `__format__()` methods. + + ```python + # Continued from the above example + + formatter = Formatter(FormatterSyntax.INTEL) + + # Change some options + formatter.uppercase_mnemonics = True + formatter.space_after_operand_separator = True + formatter.first_operand_char_index = 8 + + print(f"disasm : {formatter.format(instr)}") + print(f"mnemonic: {formatter.format_mnemonic(instr)}") + print(f"operands: {formatter.format_all_operands(instr)}") + print(f"op #0 : {formatter.format_operand(instr, 0)}") + print(f"op #1 : {formatter.format_operand(instr, 1)}") + print(f"reg RCX : {formatter.format_register(Register.RCX)}") + ``` + + Output: + + ```text + disasm : XCHG [rdx+rsi+16h], ah + mnemonic: XCHG + operands: [rdx+rsi+16h], ah + op #0 : [rdx+rsi+16h] + op #1 : ah + reg RCX : rcx + ``` + + ```python + # A formatter isn't needed if you like most of the default options. + # repr() == str() == format() all return the same thing. + print(f"disasm : {repr(instr)}") + print(f"disasm : {str(instr)}") + print(f"disasm : {instr}") + ``` + + Output: + + ```text + disasm : xchg ah,[rdx+rsi+16h] + disasm : xchg ah,[rdx+rsi+16h] + disasm : xchg ah,[rdx+rsi+16h] + ``` + + ```python + # __format__() supports a format spec argument, see the table below + print(f"disasm : {instr:f}") + print(f"disasm : {instr:g}") + print(f"disasm : {instr:i}") + print(f"disasm : {instr:m}") + print(f"disasm : {instr:n}") + print(f"disasm : {instr:gxsSG}") + ``` + + Output: + + ```text + disasm : xchg [rdx+rsi+16h],ah + disasm : xchg %ah,0x16(%rdx,%rsi) + disasm : xchg [rdx+rsi+16h],ah + disasm : xchg ah,[rdx+rsi+16h] + disasm : xchg ah,[rdx+rsi+16h] + disasm : xchgb %ah, %ds:0x16(%rdx,%rsi) + ``` + + The following format specifiers are supported in any order. If you omit the + formatter kind, the default formatter is used (eg. masm): + + ```text + F-Spec Description + ------------------- + f Fast formatter (masm-like syntax) + g GNU Assembler formatter + i Intel (XED) formatter + m masm formatter + n nasm formatter + X Uppercase hex numbers with `0x` prefix + x Lowercase hex numbers with `0x` prefix + H Uppercase hex numbers with `h` suffix + h Lowercase hex numbers with `h` suffix + r RIP-relative memory operands use RIP register instead of abs addr (`[rip+123h]` vs `[123456789ABCDEF0h]`) + U Uppercase everything except numbers and hex prefixes/suffixes (ignored by fast fmt) + s Add a space after the operand separator + S Always show the segment register + B Don't show the branch size (`SHORT` or `NEAR PTR`) (ignored by fast fmt) + G (GNU Assembler): Add mnemonic size suffix (eg. `movl` vs `mov`) + M Always show the memory size (eg. `BYTE PTR`) even when not needed + _ Use digit separators (eg. `0x12345678` vs `0x1234_5678`) (ignored by fast fmt) + ``` + """ def __init__(self) -> None: ... - def __copy__(self) -> Instruction: ... - def __deepcopy__(self, memo: Any) -> Instruction: ... - def clone(self) -> Instruction: ... - def eq_all_bits(self, other: Instruction) -> bool: ... + def __copy__(self) -> Instruction: + """ + Returns a copy of this instance. + + ### Returns: + + - Instruction: A copy of this instance + + This is identical to `Instruction.clone` + """ + ... + def __deepcopy__(self, memo: Any) -> Instruction: + """ + Returns a copy of this instance. + + ### Args: + + - `memo` (Any): memo dict + + ### Returns: + + - Instruction: A copy of this instance + + This is identical to `Instruction.clone` + """ + ... + def clone(self) -> Instruction: + """ + Returns a copy of this instance. + + ### Returns: + + - Instruction: A copy of this instance + """ + ... + def eq_all_bits(self, other: Instruction) -> bool: + """ + Checks if two instructions are equal, comparing all bits, not ignoring anything. `==` ignores some fields. + + ### Args: + + - `other` (`Instruction`): Other instruction + + ### Returns: + + - bool: `True` if `other` is exactly identical to this instance + """ + ... @property - def ip16(self) -> int: ... + def ip16(self) -> int: + """int: (`u16`) Gets the 16-bit IP of the instruction""" + ... @ip16.setter def ip16(self, new_value: int) -> None: ... @property - def ip32(self) -> int: ... + def ip32(self) -> int: + """int: (`u32`) Gets the 32-bit IP of the instruction""" + ... @ip32.setter def ip32(self, new_value: int) -> None: ... @property - def ip(self) -> int: ... + def ip(self) -> int: + """int: (`u64`) Gets the 64-bit IP of the instruction""" + ... @ip.setter def ip(self, new_value: int) -> None: ... @property - def next_ip16(self) -> int: ... + def next_ip16(self) -> int: + """int: (`u16`) Gets the 16-bit IP of the next instruction""" + ... @next_ip16.setter def next_ip16(self, new_value: int) -> None: ... @property - def next_ip32(self) -> int: ... + def next_ip32(self) -> int: + """int: (`u32`) Gets the 32-bit IP of the next instruction""" + ... @next_ip32.setter def next_ip32(self, new_value: int) -> None: ... @property - def next_ip(self) -> int: ... + def next_ip(self) -> int: + """int: (`u64`) Gets the 64-bit IP of the next instruction""" + ... @next_ip.setter def next_ip(self, new_value: int) -> None: ... @property - def code_size(self) -> CodeSize: ... + def code_size(self) -> CodeSize: + """ + `CodeSize`: Gets the code size (a `CodeSize` enum value) when the instruction was decoded. + + ### Note: + + - This value is informational and can be used by a formatter. + """ + ... @code_size.setter def code_size(self, new_value: CodeSize) -> None: ... @property - def is_invalid(self) -> bool: ... + def is_invalid(self) -> bool: + """bool: Checks if it's an invalid instruction (`Instruction.code` == `Code.INVALID`)""" + ... @property - def code(self) -> Code: ... + def code(self) -> Code: + """`Code`: Gets the instruction code (a `Code` enum value), see also `Instruction.mnemonic`""" + ... @code.setter def code(self, new_value: Code) -> None: ... @property - def mnemonic(self) -> Mnemonic: ... + def mnemonic(self) -> Mnemonic: + """`Mnemonic`: Gets the mnemonic (a `Mnemonic` enum value), see also `Instruction.code`""" + ... @property - def op_count(self) -> int: ... + def op_count(self) -> int: + """ + int: Gets the operand count. An instruction can have 0-5 operands. + + ### Examples: + + ```python + from iced_x86 import * + + # add [rax],ebx + data = b"\\x01\\x18" + decoder = Decoder(64, data) + instr = decoder.decode() + + assert instr.op_count == 2 + ``` + """ + ... @property - def len(self) -> int: ... + def len(self) -> int: + """ + int: (`u8`) Gets the length of the instruction, 0-15 bytes. + + You can also call `len(instr)` to get this value. + + ### Note: + + - This is just informational. If you modify the instruction or create a new one, this method could return the wrong value. + """ + ... @len.setter def len(self, new_value: int) -> None: ... @property - def has_xacquire_prefix(self) -> bool: ... + def has_xacquire_prefix(self) -> bool: + """bool: `True` if the instruction has the `XACQUIRE` prefix (`F2`)""" + ... @has_xacquire_prefix.setter def has_xacquire_prefix(self, new_value: bool) -> None: ... @property - def has_xrelease_prefix(self) -> bool: ... + def has_xrelease_prefix(self) -> bool: + """bool: `True` if the instruction has the `XRELEASE` prefix (`F3`)""" + ... @has_xrelease_prefix.setter def has_xrelease_prefix(self, new_value: bool) -> None: ... @property - def has_rep_prefix(self) -> bool: ... + def has_rep_prefix(self) -> bool: + """bool: `True` if the instruction has the `REPE` or `REP` prefix (`F3`)""" + ... @has_rep_prefix.setter def has_rep_prefix(self, new_value: bool) -> None: ... @property - def has_repe_prefix(self) -> bool: ... + def has_repe_prefix(self) -> bool: + """bool: `True` if the instruction has the `REPE` or `REP` prefix (`F3`)""" + ... @has_repe_prefix.setter def has_repe_prefix(self, new_value: bool) -> None: ... @property - def has_repne_prefix(self) -> bool: ... + def has_repne_prefix(self) -> bool: + """bool: `True` if the instruction has the `REPNE` prefix (`F2`)""" + ... @has_repne_prefix.setter def has_repne_prefix(self, new_value: bool) -> None: ... @property - def has_lock_prefix(self) -> bool: ... + def has_lock_prefix(self) -> bool: + """bool: `True` if the instruction has the `LOCK` prefix (`F0`)""" + ... @has_lock_prefix.setter def has_lock_prefix(self, new_value: bool) -> None: ... @property - def op0_kind(self) -> OpKind: ... + def op0_kind(self) -> OpKind: + """`OpKind`: Gets operand #0's kind (an `OpKind` enum value) if the operand exists (see `Instruction.op_count` and `Instruction.op_kind`)""" + ... @op0_kind.setter def op0_kind(self, new_value: OpKind) -> None: ... @property - def op1_kind(self) -> OpKind: ... + def op1_kind(self) -> OpKind: + """`OpKind`: Gets operand #1's kind (an `OpKind` enum value) if the operand exists (see `Instruction.op_count` and `Instruction.op_kind`)""" + ... @op1_kind.setter def op1_kind(self, new_value: OpKind) -> None: ... @property - def op2_kind(self) -> OpKind: ... + def op2_kind(self) -> OpKind: + """`OpKind`: Gets operand #2's kind (an `OpKind` enum value) if the operand exists (see `Instruction.op_count` and `Instruction.op_kind`)""" + ... @op2_kind.setter def op2_kind(self, new_value: OpKind) -> None: ... @property - def op3_kind(self) -> OpKind: ... + def op3_kind(self) -> OpKind: + """`OpKind`: Gets operand #3's kind (an `OpKind` enum value) if the operand exists (see `Instruction.op_count` and `Instruction.op_kind`)""" + ... @op3_kind.setter def op3_kind(self, new_value: OpKind) -> None: ... @property - def op4_kind(self) -> OpKind: ... + def op4_kind(self) -> OpKind: + """`OpKind`: Gets operand #4's kind (an `OpKind` enum value) if the operand exists (see `Instruction.op_count` and `Instruction.op_kind`)""" + ... @op4_kind.setter def op4_kind(self, new_value: OpKind) -> None: ... - def op_kind(self, operand: int) -> OpKind: ... - def set_op_kind(self, operand: int, op_kind: OpKind) -> None: ... + def op_kind(self, operand: int) -> OpKind: + """ + Gets an operand's kind (an `OpKind` enum value) if it exists (see `Instruction.op_count`) + + ### Args: + + - `operand` (int): Operand number, 0-4 + + ### Returns: + + - `OpKind`: The operand's operand kind + + ### Raises: + + - ValueError: If `operand` is invalid + + ### Examples: + + ```python + from iced_x86 import * + + # add [rax],ebx + data = b"\\x01\\x18" + decoder = Decoder(64, data) + instr = decoder.decode() + + assert instr.op_count == 2 + assert instr.op_kind(0) == OpKind.MEMORY + assert instr.memory_base == Register.RAX + assert instr.memory_index == Register.NONE + assert instr.op_kind(1) == OpKind.REGISTER + assert instr.op_register(1) == Register.EBX + ``` + """ + ... + def set_op_kind(self, operand: int, op_kind: OpKind) -> None: + """ + Sets an operand's kind + + ### Args: + + - `operand` (int): Operand number, 0-4 + - `op_kind` (`OpKind`): Operand kind + + ### Raises: + + - ValueError: If `operand` is invalid + """ + ... @property - def has_segment_prefix(self) -> bool: ... + def has_segment_prefix(self) -> bool: + """bool: Checks if the instruction has a segment override prefix, see `Instruction.segment_prefix`""" + ... @property - def segment_prefix(self) -> Register: ... + def segment_prefix(self) -> Register: + """ + `Register`: Gets the segment override prefix (a `Register` enum value) or `Register.NONE` if none. + + See also `Instruction.memory_segment`. + + Use this method if the operand has kind `OpKind.MEMORY`, `OpKind.MEMORY64`, + `OpKind.MEMORY_SEG_SI`, `OpKind.MEMORY_SEG_ESI`, `OpKind.MEMORY_SEG_RSI` + """ + ... @segment_prefix.setter def segment_prefix(self, new_value: Register) -> None: ... @property - def memory_segment(self) -> Register: ... + def memory_segment(self) -> Register: + """ + `Register`: Gets the effective segment register used to reference the memory location (a `Register` enum value). + + Use this method if the operand has kind `OpKind.MEMORY`, `OpKind.MEMORY64`, + `OpKind.MEMORY_SEG_SI`, `OpKind.MEMORY_SEG_ESI`, `OpKind.MEMORY_SEG_RSI` + """ + ... @property - def memory_displ_size(self) -> int: ... + def memory_displ_size(self) -> int: + """ + int: (`u8`) Gets the size of the memory displacement in bytes. + + Valid values are `0`, `1` (16/32/64-bit), `2` (16-bit), `4` (32-bit), `8` (64-bit). + + Note that the return value can be 1 and `Instruction.memory_displacement` may still not fit in + a signed byte if it's an EVEX encoded instruction. + + Use this method if the operand has kind `OpKind.MEMORY` + """ + ... @memory_displ_size.setter def memory_displ_size(self, new_value: int) -> None: ... @property - def is_broadcast(self) -> bool: ... + def is_broadcast(self) -> bool: + """bool: `True` if the data is broadcasted (EVEX instructions only)""" + ... @is_broadcast.setter def is_broadcast(self, new_value: bool) -> None: ... @property - def memory_size(self) -> MemorySize: ... + def memory_size(self) -> MemorySize: + """ + `MemorySize`: Gets the size of the memory location (a `MemorySize` enum value) that is referenced by the operand. + + See also `Instruction.is_broadcast`. + + Use this method if the operand has kind `OpKind.MEMORY`, `OpKind.MEMORY64`, + `OpKind.MEMORY_SEG_SI`, `OpKind.MEMORY_SEG_ESI`, `OpKind.MEMORY_SEG_RSI`, + `OpKind.MEMORY_ESDI`, `OpKind.MEMORY_ESEDI`, `OpKind.MEMORY_ESRDI` + """ + ... @property - def memory_index_scale(self) -> int: ... + def memory_index_scale(self) -> int: + """ + int: (`u8`) Gets the index register scale value, valid values are `*1`, `*2`, `*4`, `*8`. + + Use this method if the operand has kind `OpKind.MEMORY` + """ + ... @memory_index_scale.setter def memory_index_scale(self, new_value: int) -> None: ... @property - def memory_displacement(self) -> int: ... + def memory_displacement(self) -> int: + """ + int: (`u32`) Gets the memory operand's displacement. + + This should be sign extended to 64 bits if it's 64-bit addressing (see `Instruction.memory_displacement64`). + + Use this method if the operand has kind `OpKind.MEMORY` + """ + ... @memory_displacement.setter def memory_displacement(self, new_value: int) -> None: ... @property - def memory_displacement64(self) -> int: ... - def immediate(self, operand: int) -> int: ... - def set_immediate_i32(self, operand: int, new_value: int) -> None: ... - def set_immediate_u32(self, operand: int, new_value: int) -> None: ... - def set_immediate_i64(self, operand: int, new_value: int) -> None: ... - def set_immediate_u64(self, operand: int, new_value: int) -> None: ... + def memory_displacement64(self) -> int: + """ + int: (`u64`) Gets the memory operand's displacement sign extended to 64 bits. + + Use this method if the operand has kind `OpKind.MEMORY` + """ + ... + def immediate(self, operand: int) -> int: + """ + Gets an operand's immediate value + + ### Args: + + - `operand` (int): Operand number, 0-4 + + ### Returns: + + - int: (`u64`) The immediate + + ### Raises: + + - ValueError: If `operand` is invalid or not immediate. + """ + ... + def set_immediate_i32(self, operand: int, new_value: int) -> None: + """ + Sets an operand's immediate value + + ### Args: + + - `operand` (int): Operand number, 0-4 + - `new_value` (int): (`i32`) Immediate + + ### Raises: + + - ValueError: If `operand` is invalid or if it's not an immediate operand + """ + ... + def set_immediate_u32(self, operand: int, new_value: int) -> None: + """ + Sets an operand's immediate value + + ### Args: + + - `operand` (int): Operand number, 0-4 + - `new_value` (int): (`u32`) Immediate + + ### Raises: + + - ValueError: If `operand` is invalid or if it's not an immediate operand + """ + ... + def set_immediate_i64(self, operand: int, new_value: int) -> None: + """ + Sets an operand's immediate value + + ### Args: + + - `operand` (int): Operand number, 0-4 + - `new_value` (int): (`i64`) Immediate + + ### Raises: + + - ValueError: If `operand` is invalid or if it's not an immediate operand + """ + ... + def set_immediate_u64(self, operand: int, new_value: int) -> None: + """ + Sets an operand's immediate value + + ### Args: + + - `operand` (int): Operand number, 0-4 + - `new_value` (int): (`u64`) Immediate + + ### Raises: + + - ValueError: If `operand` is invalid or if it's not an immediate operand + """ + ... @property - def immediate8(self) -> int: ... + def immediate8(self) -> int: + """ + int: (`u8`) Gets the operand's immediate value. + + Use this method if the operand has kind `OpKind.IMMEDIATE8` + """ + ... @immediate8.setter def immediate8(self, new_value: int) -> None: ... @property - def immediate8_2nd(self) -> int: ... + def immediate8_2nd(self) -> int: + """ + int: (`u8`) Gets the operand's immediate value. + + Use this method if the operand has kind `OpKind.IMMEDIATE8_2ND` + """ + ... @immediate8_2nd.setter def immediate8_2nd(self, new_value: int) -> None: ... @property - def immediate16(self) -> int: ... + def immediate16(self) -> int: + """ + int: (`u16`) Gets the operand's immediate value. + + Use this method if the operand has kind `OpKind.IMMEDIATE16` + """ + ... @immediate16.setter def immediate16(self, new_value: int) -> None: ... @property - def immediate32(self) -> int: ... + def immediate32(self) -> int: + """ + int: (`u32`) Gets the operand's immediate value. + + Use this method if the operand has kind `OpKind.IMMEDIATE32` + """ + ... @immediate32.setter def immediate32(self, new_value: int) -> None: ... @property - def immediate64(self) -> int: ... + def immediate64(self) -> int: + """ + int: (`u64`) Gets the operand's immediate value. + + Use this method if the operand has kind `OpKind.IMMEDIATE64` + """ + ... @immediate64.setter def immediate64(self, new_value: int) -> None: ... @property - def immediate8to16(self) -> int: ... + def immediate8to16(self) -> int: + """ + int: (`i16`) Gets the operand's immediate value. + + Use this method if the operand has kind `OpKind.IMMEDIATE8TO16` + """ + ... @immediate8to16.setter def immediate8to16(self, new_value: int) -> None: ... @property - def immediate8to32(self) -> int: ... + def immediate8to32(self) -> int: + """ + int: (`i32`) Gets the operand's immediate value. + + Use this method if the operand has kind `OpKind.IMMEDIATE8TO32` + """ + ... @immediate8to32.setter def immediate8to32(self, new_value: int) -> None: ... @property - def immediate8to64(self) -> int: ... + def immediate8to64(self) -> int: + """ + int: (`i64`) Gets the operand's immediate value. + + Use this method if the operand has kind `OpKind.IMMEDIATE8TO64` + """ + ... @immediate8to64.setter def immediate8to64(self, new_value: int) -> None: ... @property - def immediate32to64(self) -> int: ... + def immediate32to64(self) -> int: + """ + int: (`i64`) Gets the operand's immediate value. + + Use this method if the operand has kind `OpKind.IMMEDIATE32TO64` + """ + ... @immediate32to64.setter def immediate32to64(self, new_value: int) -> None: ... @property - def memory_address64(self) -> int: ... + def memory_address64(self) -> int: + """ + int: (`u64`) Gets the operand's 64-bit address value. + + Use this method if the operand has kind `OpKind.MEMORY64` + """ + ... @memory_address64.setter def memory_address64(self, new_value: int) -> None: ... @property - def near_branch16(self) -> int: ... + def near_branch16(self) -> int: + """ + int: (`u16`) Gets the operand's branch target. + + Use this method if the operand has kind `OpKind.NEAR_BRANCH16` + """ + ... @near_branch16.setter def near_branch16(self, new_value: int) -> None: ... @property - def near_branch32(self) -> int: ... + def near_branch32(self) -> int: + """ + int: (`u32`) Gets the operand's branch target. + + Use this method if the operand has kind `OpKind.NEAR_BRANCH32` + """ + ... @near_branch32.setter def near_branch32(self, new_value: int) -> None: ... @property - def near_branch64(self) -> int: ... + def near_branch64(self) -> int: + """ + int: (`u64`) Gets the operand's branch target. + + Use this method if the operand has kind `OpKind.NEAR_BRANCH64` + """ + ... @near_branch64.setter def near_branch64(self, new_value: int) -> None: ... @property - def near_branch_target(self) -> int: ... + def near_branch_target(self) -> int: + """ + int: (`u64`) Gets the near branch target if it's a `CALL`/`JMP`/`Jcc` near branch instruction + + (i.e., if `Instruction.op0_kind` is `OpKind.NEAR_BRANCH16`, `OpKind.NEAR_BRANCH32` or `OpKind.NEAR_BRANCH64`) + """ + ... @property - def far_branch16(self) -> int: ... + def far_branch16(self) -> int: + """ + int: (`u16`) Gets the operand's branch target. + + Use this method if the operand has kind `OpKind.FAR_BRANCH16` + """ + ... @far_branch16.setter def far_branch16(self, new_value: int) -> None: ... @property - def far_branch32(self) -> int: ... + def far_branch32(self) -> int: + """ + int: (`u32`) Gets the operand's branch target. + + Use this method if the operand has kind `OpKind.FAR_BRANCH32` + """ + ... @far_branch32.setter def far_branch32(self, new_value: int) -> None: ... @property - def far_branch_selector(self) -> int: ... + def far_branch_selector(self) -> int: + """ + int: (`16`) Gets the operand's branch target selector. + + Use this method if the operand has kind `OpKind.FAR_BRANCH16` or `OpKind.FAR_BRANCH32` + """ + ... @far_branch_selector.setter def far_branch_selector(self, new_value: int) -> None: ... @property - def memory_base(self) -> Register: ... + def memory_base(self) -> Register: + """ + `Register`: Gets the memory operand's base register (a `Register` enum value) or `Register.NONE` if none. + + Use this method if the operand has kind `OpKind.MEMORY` + """ + ... @memory_base.setter def memory_base(self, new_value: Register) -> None: ... @property - def memory_index(self) -> Register: ... + def memory_index(self) -> Register: + """ + `Register`: Gets the memory operand's index register (a `Register` enum value) or `Register.NONE` if none. + + Use this method if the operand has kind `OpKind.MEMORY` + """ + ... @memory_index.setter def memory_index(self, new_value: Register) -> None: ... @property - def op0_register(self) -> Register: ... + def op0_register(self) -> Register: + """ + `Register`: Gets operand #0's register value (a `Register` enum value). + + Use this method if operand #0 (`Instruction.op0_kind`) has kind `OpKind.REGISTER`, see `Instruction.op_count` and `Instruction.op_register` + """ + ... @op0_register.setter def op0_register(self, new_value: Register) -> None: ... @property - def op1_register(self) -> Register: ... + def op1_register(self) -> Register: + """ + `Register`: Gets operand #1's register value (a `Register` enum value). + + Use this method if operand #1 (`Instruction.op0_kind`) has kind `OpKind.REGISTER`, see `Instruction.op_count` and `Instruction.op_register` + """ + ... @op1_register.setter def op1_register(self, new_value: Register) -> None: ... @property - def op2_register(self) -> Register: ... + def op2_register(self) -> Register: + """ + `Register`: Gets operand #2's register value (a `Register` enum value). + + Use this method if operand #2 (`Instruction.op0_kind`) has kind `OpKind.REGISTER`, see `Instruction.op_count` and `Instruction.op_register` + """ + ... @op2_register.setter def op2_register(self, new_value: Register) -> None: ... @property - def op3_register(self) -> Register: ... + def op3_register(self) -> Register: + """ + `Register`: Gets operand #3's register value (a `Register` enum value). + + Use this method if operand #3 (`Instruction.op0_kind`) has kind `OpKind.REGISTER`, see `Instruction.op_count` and `Instruction.op_register` + """ + ... @op3_register.setter def op3_register(self, new_value: Register) -> None: ... @property - def op4_register(self) -> Register: ... + def op4_register(self) -> Register: + """ + `Register`: Gets operand #4's register value (a `Register` enum value). + + Use this method if operand #4 (`Instruction.op0_kind`) has kind `OpKind.REGISTER`, see `Instruction.op_count` and `Instruction.op_register` + """ + ... @op4_register.setter def op4_register(self, new_value: Register) -> None: ... - def op_register(self, operand: int) -> Register: ... - def set_op_register(self, operand: int, new_value: Register) -> None: ... + def op_register(self, operand: int) -> Register: + """ + Gets the operand's register value (a `Register` enum value). + + Use this method if the operand has kind `OpKind.REGISTER` + + ### Args: + + - `operand` (int): Operand number, 0-4 + + ### Returns: + + - `Register`: The operand's register value + + ### Raises: + + - ValueError: If `operand` is invalid + + ### Examples: + + ```python + from iced_x86 import * + + # add [rax],ebx + data = b"\\x01\\x18" + decoder = Decoder(64, data) + instr = decoder.decode() + + assert instr.op_count == 2 + assert instr.op_kind(0) == OpKind.MEMORY + assert instr.op_kind(1) == OpKind.REGISTER + assert instr.op_register(1) == Register.EBX + ``` + """ + ... + def set_op_register(self, operand: int, new_value: Register) -> None: + """ + Sets the operand's register value. + + Use this method if the operand has kind `OpKind.REGISTER` + + ### Args: + + - `operand` (int): Operand number, 0-4 + - `new_value` (`Register`): New value + + ### Raises: + + - ValueError: If `operand` is invalid + """ + ... @property - def op_mask(self) -> Register: ... + def op_mask(self) -> Register: + """`Register`: Gets the op mask register (`Register.K1` - `Register.K7`) or `Register.NONE` if none (a `Register` enum value)""" + ... @op_mask.setter def op_mask(self, new_value: Register) -> None: ... @property - def has_op_mask(self) -> bool: ... + def has_op_mask(self) -> bool: + """bool: Checks if there's an op mask register (`Instruction.op_mask`)""" + ... @property - def zeroing_masking(self) -> bool: ... + def zeroing_masking(self) -> bool: + """ + bool: `True` if zeroing-masking, `False` if merging-masking. + + Only used by most EVEX encoded instructions that use op mask registers. + """ + ... @zeroing_masking.setter def zeroing_masking(self, new_value: bool) -> None: ... @property - def merging_masking(self) -> bool: ... + def merging_masking(self) -> bool: + """ + bool: `True` if merging-masking, `False` if zeroing-masking. + + Only used by most EVEX encoded instructions that use op mask registers. + """ + ... @merging_masking.setter def merging_masking(self, new_value: bool) -> None: ... @property - def rounding_control(self) -> RoundingControl: ... + def rounding_control(self) -> RoundingControl: + """ + `RoundingControl`: Gets the rounding control (a `RoundingControl` enum value) or `RoundingControl.NONE` if the instruction doesn't use it. + + ### Note: + + - SAE is implied but `Instruction.suppress_all_exceptions` still returns `False`. + """ + ... @rounding_control.setter def rounding_control(self, new_value: RoundingControl) -> None: ... @property - def declare_data_len(self) -> int: ... + def declare_data_len(self) -> int: + """ + int: (`u8`) Gets the number of elements in a `db`/`dw`/`dd`/`dq` directive. + + Can only be called if `Instruction.code` is `Code.DECLAREBYTE`, `Code.DECLAREWORD`, `Code.DECLAREDWORD`, `Code.DECLAREQWORD` + """ + ... @declare_data_len.setter def declare_data_len(self, new_value: int) -> None: ... - def set_declare_byte_value_i8(self, index: int, new_value: int) -> None: ... - def set_declare_byte_value(self, index: int, new_value: int) -> None: ... - def get_declare_byte_value(self, index: int) -> int: ... - def get_declare_byte_value_i8(self, index: int) -> int: ... - def set_declare_word_value_i16(self, index: int, new_value: int) -> None: ... - def set_declare_word_value(self, index: int, new_value: int) -> None: ... - def get_declare_word_value(self, index: int) -> int: ... - def get_declare_word_value_i16(self, index: int) -> int: ... - def set_declare_dword_value_i32(self, index: int, new_value: int) -> None: ... - def set_declare_dword_value(self, index: int, new_value: int) -> None: ... - def get_declare_dword_value(self, index: int) -> int: ... - def get_declare_dword_value_i32(self, index: int) -> int: ... - def set_declare_qword_value_i64(self, index: int, new_value: int) -> None: ... - def set_declare_qword_value(self, index: int, new_value: int) -> None: ... - def get_declare_qword_value(self, index: int) -> int: ... - def get_declare_qword_value_i64(self, index: int) -> int: ... + def set_declare_byte_value_i8(self, index: int, new_value: int) -> None: + """ + Sets a new `db` value, see also `Instruction.declare_data_len`. + + Can only be called if `Instruction.code` is `Code.DECLAREBYTE` + + ### Args: + + - `index` (int): Index (0-15) + - `new_value` (int): (`i8`) New value + + ### Raises: + + - ValueError: If `index` is invalid + """ + ... + def set_declare_byte_value(self, index: int, new_value: int) -> None: + """ + Sets a new `db` value, see also `Instruction.declare_data_len`. + + Can only be called if `Instruction.code` is `Code.DECLAREBYTE` + + ### Args: + + - `index` (int): Index (0-15) + - `new_value` (int): (`u8`) New value + + ### Raises: + + - ValueError: If `index` is invalid + """ + ... + def get_declare_byte_value(self, index: int) -> int: + """ + Gets a `db` value, see also `Instruction.declare_data_len`. + + Can only be called if `Instruction.code` is `Code.DECLAREBYTE` + + ### Args: + + - `index` (int): Index (0-15) + + ### Returns: + + - int: (`u8`) The value + + ### Raises: + + - ValueError: If `index` is invalid + """ + ... + def get_declare_byte_value_i8(self, index: int) -> int: + """ + Gets a `db` value, see also `Instruction.declare_data_len`. + + Can only be called if `Instruction.code` is `Code.DECLAREBYTE` + + ### Args: + + - `index` (int): Index (0-15) + + ### Returns: + + - int: (`i8`) The value + + ### Raises: + + - ValueError: If `index` is invalid + """ + ... + def set_declare_word_value_i16(self, index: int, new_value: int) -> None: + """ + Sets a new `dw` value, see also `Instruction.declare_data_len`. + + Can only be called if `Instruction.code` is `Code.DECLAREWORD` + + ### Args: + + - `index` (int): Index (0-7) + - `new_value` (int): (`i16`) New value + + ### Raises: + + - ValueError: If `index` is invalid + """ + ... + def set_declare_word_value(self, index: int, new_value: int) -> None: + """ + Sets a new `dw` value, see also `Instruction.declare_data_len`. + + Can only be called if `Instruction.code` is `Code.DECLAREWORD` + + ### Args: + + - `index` (int): Index (0-7) + - `new_value` (int): (`u16`) New value + + ### Raises: + + - ValueError: If `index` is invalid + """ + ... + def get_declare_word_value(self, index: int) -> int: + """ + Gets a `dw` value, see also `Instruction.declare_data_len`. + + Can only be called if `Instruction.code` is `Code.DECLAREWORD` + + ### Args: + + - `index` (int): Index (0-7) + + ### Returns: + + - int: (`u16`) The value + + ### Raises: + + - ValueError: If `index` is invalid + """ + ... + def get_declare_word_value_i16(self, index: int) -> int: + """ + Gets a `dw` value, see also `Instruction.declare_data_len`. + + Can only be called if `Instruction.code` is `Code.DECLAREWORD` + + ### Args: + + - `index` (int): Index (0-7) + + ### Returns: + + - int: (`i16`) The value + + ### Raises: + + - ValueError: If `index` is invalid + """ + ... + def set_declare_dword_value_i32(self, index: int, new_value: int) -> None: + """ + Sets a new `dd` value, see also `Instruction.declare_data_len`. + + Can only be called if `Instruction.code` is `Code.DECLAREDWORD` + + ### Args: + + - `index` (int): Index (0-3) + - `new_value` (int): (`i32`) New value + + ### Raises: + + - ValueError: If `index` is invalid + """ + ... + def set_declare_dword_value(self, index: int, new_value: int) -> None: + """ + Sets a new `dd` value, see also `Instruction.declare_data_len`. + + Can only be called if `Instruction.code` is `Code.DECLAREDWORD` + + ### Args: + + - `index` (int): Index (0-3) + - `new_value` (int): (`u32`) New value + + ### Raises: + + - ValueError: If `index` is invalid + """ + ... + def get_declare_dword_value(self, index: int) -> int: + """ + Gets a `dd` value, see also `Instruction.declare_data_len`. + + Can only be called if `Instruction.code` is `Code.DECLAREDWORD` + + ### Args: + + - `index` (int): Index (0-3) + + ### Returns: + + - int: (`u32`) The value + + ### Raises: + + - ValueError: If `index` is invalid + """ + ... + def get_declare_dword_value_i32(self, index: int) -> int: + """ + Gets a `dd` value, see also `Instruction.declare_data_len`. + + Can only be called if `Instruction.code` is `Code.DECLAREDWORD` + + ### Args: + + - `index` (int): Index (0-3) + + ### Returns: + + - int: (`i32`) The value + + ### Raises: + + - ValueError: If `index` is invalid + """ + ... + def set_declare_qword_value_i64(self, index: int, new_value: int) -> None: + """ + Sets a new `dq` value, see also `Instruction.declare_data_len`. + + Can only be called if `Instruction.code` is `Code.DECLAREQWORD` + + ### Args: + + - `index` (int): Index (0-1) + - `new_value` (int): (`i64`) New value + + ### Raises: + + - ValueError: If `index` is invalid + """ + ... + def set_declare_qword_value(self, index: int, new_value: int) -> None: + """ + Sets a new `dq` value, see also `Instruction.declare_data_len`. + + Can only be called if `Instruction.code` is `Code.DECLAREQWORD` + + ### Args: + + - `index` (int): Index (0-1) + - `new_value` (int): (`u64`) New value + + ### Raises: + + - ValueError: If `index` is invalid + """ + ... + def get_declare_qword_value(self, index: int) -> int: + """ + Gets a `dq` value, see also `Instruction.declare_data_len`. + + Can only be called if `Instruction.code` is `Code.DECLAREQWORD` + + ### Args: + + - `index` (int): Index (0-1) + + ### Returns: + + - int: (`u64`) The value + + ### Raises: + + - ValueError: If `index` is invalid + """ + ... + def get_declare_qword_value_i64(self, index: int) -> int: + """ + Gets a `dq` value, see also `Instruction.declare_data_len`. + + Can only be called if `Instruction.code` is `Code.DECLAREQWORD` + + ### Args: + + - `index` (int): Index (0-1) + + ### Returns: + + - int: (`i64`) The value + + ### Raises: + + - ValueError: If `index` is invalid + """ + ... @property - def is_vsib(self) -> bool: ... + def is_vsib(self) -> bool: + """bool: Checks if this is a VSIB instruction, see also `Instruction.is_vsib32`, `Instruction.is_vsib64`""" + ... @property - def is_vsib32(self) -> bool: ... + def is_vsib32(self) -> bool: + """bool: VSIB instructions only (`Instruction.is_vsib`): `True` if it's using 32-bit indexes, `False` if it's using 64-bit indexes""" + ... @property - def is_vsib64(self) -> bool: ... + def is_vsib64(self) -> bool: + """bool: VSIB instructions only (`Instruction.is_vsib`): `True` if it's using 64-bit indexes, `False` if it's using 32-bit indexes""" + ... @property - def vsib(self) -> Optional[bool]: ... + def vsib(self) -> Optional[bool]: + """ + bool, None: Checks if it's a vsib instruction. + + - Returns `True` if it's a VSIB instruction with 64-bit indexes + - Returns `False` if it's a VSIB instruction with 32-bit indexes + - Returns `None` if it's not a VSIB instruction. + """ + ... @property - def suppress_all_exceptions(self) -> bool: ... + def suppress_all_exceptions(self) -> bool: + """bool: Gets the suppress all exceptions flag (EVEX encoded instructions). Note that if `Instruction.rounding_control` is not `RoundingControl.NONE`, SAE is implied but this method will still return `False`.""" + ... @suppress_all_exceptions.setter def suppress_all_exceptions(self, new_value: bool) -> None: ... @property - def is_ip_rel_memory_operand(self) -> bool: ... + def is_ip_rel_memory_operand(self) -> bool: + """bool: Checks if the memory operand is `RIP`/`EIP` relative""" + ... @property - def ip_rel_memory_address(self) -> int: ... + def ip_rel_memory_address(self) -> int: + """ + int: (`u64`) Gets the `RIP`/`EIP` releative address ((`Instruction.next_ip` or `Instruction.next_ip32`) + `Instruction.memory_displacement`). + + This method is only valid if there's a memory operand with `RIP`/`EIP` relative addressing, see `Instruction.is_ip_rel_memory_operand` + """ + ... @property - def stack_pointer_increment(self) -> int: ... - def fpu_stack_increment_info(self) -> FpuStackIncrementInfo: ... + def stack_pointer_increment(self) -> int: + """ + int: (`i32`) Gets the number of bytes added to `SP`/`ESP`/`RSP` or 0 if it's not an instruction that pushes or pops data. + + This method assumes the instruction doesn't change the privilege level (eg. `IRET/D/Q`). If it's the `LEAVE` + instruction, this method returns 0. + + ### Examples: + + ```python + from iced_x86 import * + + # pushfq + data = b"\\x9C" + decoder = Decoder(64, data) + instr = decoder.decode() + + assert instr.is_stack_instruction + assert instr.stack_pointer_increment == -8 + ``` + """ + ... + def fpu_stack_increment_info(self) -> FpuStackIncrementInfo: + """ + Gets the FPU status word's `TOP` increment and whether it's a conditional or unconditional push/pop and whether `TOP` is written. + + ### Returns: + + - `FpuStackIncrementInfo`: FPU stack info + + ### Examples: + + ```python + from iced_x86 import * + + # ficomp dword ptr [rax] + data = b"\\xDA\\x18" + decoder = Decoder(64, data) + instr = decoder.decode() + + info = instr.fpu_stack_increment_info() + # It pops the stack once + assert info.increment == 1 + assert not info.conditional + assert info.writes_top + ``` + """ + ... @property - def encoding(self) -> EncodingKind: ... - def cpuid_features(self) -> List[CpuidFeature]: ... + def encoding(self) -> EncodingKind: + """ + `EncodingKind`: Instruction encoding, eg. Legacy, 3DNow!, VEX, EVEX, XOP (an `EncodingKind` enum value) + + ### Examples: + + ```python + from iced_x86 import * + + # vmovaps xmm1,xmm5 + data = b"\\xC5\\xF8\\x28\\xCD" + decoder = Decoder(64, data) + instr = decoder.decode() + + assert instr.encoding == EncodingKind.VEX + ``` + """ + ... + def cpuid_features(self) -> List[CpuidFeature]: + """ + Gets the CPU or CPUID feature flags (a list of `CpuidFeature` enum values) + + ### Returns: + + - List[CpuidFeature]: CPU or CPUID feature flags + + ### Examples: + + ```python + from iced_x86 import * + + # vmovaps xmm1,xmm5 + # vmovaps xmm10{k3}{z},xmm19 + data = b"\\xC5\\xF8\\x28\\xCD\\x62\\x31\\x7C\\x8B\\x28\\xD3" + decoder = Decoder(64, data) + + # vmovaps xmm1,xmm5 + instr = decoder.decode() + cpuid = instr.cpuid_features() + assert len(cpuid) == 1 + assert cpuid[0] == CpuidFeature.AVX + + # vmovaps xmm10{k3}{z},xmm19 + instr = decoder.decode() + cpuid = instr.cpuid_features() + assert len(cpuid) == 2 + assert cpuid[0] == CpuidFeature.AVX512VL + assert cpuid[1] == CpuidFeature.AVX512F + ``` + """ + ... @property - def flow_control(self) -> FlowControl: ... + def flow_control(self) -> FlowControl: + """ + `FlowControl`: Control flow info (a `FlowControl` enum value) + + ### Examples: + + ```python + from iced_x86 import * + + # or ecx,esi + # ud0 rcx,rsi + # call rcx + data = b"\\x0B\\xCE\\x48\\x0F\\xFF\\xCE\\xFF\\xD1" + decoder = Decoder(64, data) + + # or ecx,esi + instr = decoder.decode() + assert instr.flow_control == FlowControl.NEXT + + # ud0 rcx,rsi + instr = decoder.decode() + assert instr.flow_control == FlowControl.EXCEPTION + + # call rcx + instr = decoder.decode() + assert instr.flow_control == FlowControl.INDIRECT_CALL + ``` + """ + ... @property - def is_privileged(self) -> bool: ... + def is_privileged(self) -> bool: + """bool: `True` if it's a privileged instruction (all CPL=0 instructions (except `VMCALL`) and IOPL instructions `IN`, `INS`, `OUT`, `OUTS`, `CLI`, `STI`)""" + ... @property - def is_stack_instruction(self) -> bool: ... + def is_stack_instruction(self) -> bool: + """ + bool: `True` if this is an instruction that implicitly uses the stack pointer (`SP`/`ESP`/`RSP`), eg. `CALL`, `PUSH`, `POP`, `RET`, etc. + + See also `Instruction.stack_pointer_increment` + + ### Examples: + + ```python + from iced_x86 import * + + # or ecx,esi + # push rax + data = b"\\x0B\\xCE\\x50" + decoder = Decoder(64, data) + + # or ecx,esi + instr = decoder.decode() + assert not instr.is_stack_instruction + + # push rax + instr = decoder.decode() + assert instr.is_stack_instruction + assert instr.stack_pointer_increment == -8 + ``` + """ + ... @property - def is_save_restore_instruction(self) -> bool: ... + def is_save_restore_instruction(self) -> bool: + """bool: `True` if it's an instruction that saves or restores too many registers (eg. `FXRSTOR`, `XSAVE`, etc).""" + ... @property - def rflags_read(self) -> RflagsBits: ... + def rflags_read(self) -> RflagsBits: + """ + `RflagsBits`: All flags that are read by the CPU when executing the instruction. + + This method returns a `RflagsBits` value. See also `Instruction.rflags_modified`. + + ### Examples: + + ```python + from iced_x86 import * + + # adc rsi,rcx + # xor rdi,5Ah + data = b"\\x48\\x11\\xCE\\x48\\x83\\xF7\\x5A" + decoder = Decoder(64, data) + + # adc rsi,rcx + instr = decoder.decode() + assert instr.rflags_read == RflagsBits.CF + assert instr.rflags_written == RflagsBits.OF | RflagsBits.SF | RflagsBits.ZF | RflagsBits.AF | RflagsBits.CF | RflagsBits.PF + assert instr.rflags_cleared == RflagsBits.NONE + assert instr.rflags_set == RflagsBits.NONE + assert instr.rflags_undefined == RflagsBits.NONE + assert instr.rflags_modified == RflagsBits.OF | RflagsBits.SF | RflagsBits.ZF | RflagsBits.AF | RflagsBits.CF | RflagsBits.PF + + # xor rdi,5Ah + instr = decoder.decode() + assert instr.rflags_read == RflagsBits.NONE + assert instr.rflags_written == RflagsBits.SF | RflagsBits.ZF | RflagsBits.PF + assert instr.rflags_cleared == RflagsBits.OF | RflagsBits.CF + assert instr.rflags_set == RflagsBits.NONE + assert instr.rflags_undefined == RflagsBits.AF + assert instr.rflags_modified == RflagsBits.OF | RflagsBits.SF | RflagsBits.ZF | RflagsBits.AF | RflagsBits.CF | RflagsBits.PF + ``` + """ + ... @property - def rflags_written(self) -> RflagsBits: ... + def rflags_written(self) -> RflagsBits: + """ + `RflagsBits`: All flags that are written by the CPU, except those flags that are known to be undefined, always set or always cleared. + + This method returns a `RflagsBits` value. See also `Instruction.rflags_modified`. + + ### Examples: + + ```python + from iced_x86 import * + + # adc rsi,rcx + # xor rdi,5Ah + data = b"\\x48\\x11\\xCE\\x48\\x83\\xF7\\x5A" + decoder = Decoder(64, data) + + # adc rsi,rcx + instr = decoder.decode() + assert instr.rflags_read == RflagsBits.CF + assert instr.rflags_written == RflagsBits.OF | RflagsBits.SF | RflagsBits.ZF | RflagsBits.AF | RflagsBits.CF | RflagsBits.PF + assert instr.rflags_cleared == RflagsBits.NONE + assert instr.rflags_set == RflagsBits.NONE + assert instr.rflags_undefined == RflagsBits.NONE + assert instr.rflags_modified == RflagsBits.OF | RflagsBits.SF | RflagsBits.ZF | RflagsBits.AF | RflagsBits.CF | RflagsBits.PF + + # xor rdi,5Ah + instr = decoder.decode() + assert instr.rflags_read == RflagsBits.NONE + assert instr.rflags_written == RflagsBits.SF | RflagsBits.ZF | RflagsBits.PF + assert instr.rflags_cleared == RflagsBits.OF | RflagsBits.CF + assert instr.rflags_set == RflagsBits.NONE + assert instr.rflags_undefined == RflagsBits.AF + assert instr.rflags_modified == RflagsBits.OF | RflagsBits.SF | RflagsBits.ZF | RflagsBits.AF | RflagsBits.CF | RflagsBits.PF + ``` + """ + ... @property - def rflags_cleared(self) -> RflagsBits: ... + def rflags_cleared(self) -> RflagsBits: + """ + `RflagsBits`: All flags that are always cleared by the CPU. + + This method returns a `RflagsBits` value. See also `Instruction.rflags_modified`. + + ### Examples: + + ```python + from iced_x86 import * + + # adc rsi,rcx + # xor rdi,5Ah + data = b"\\x48\\x11\\xCE\\x48\\x83\\xF7\\x5A" + decoder = Decoder(64, data) + + # adc rsi,rcx + instr = decoder.decode() + assert instr.rflags_read == RflagsBits.CF + assert instr.rflags_written == RflagsBits.OF | RflagsBits.SF | RflagsBits.ZF | RflagsBits.AF | RflagsBits.CF | RflagsBits.PF + assert instr.rflags_cleared == RflagsBits.NONE + assert instr.rflags_set == RflagsBits.NONE + assert instr.rflags_undefined == RflagsBits.NONE + assert instr.rflags_modified == RflagsBits.OF | RflagsBits.SF | RflagsBits.ZF | RflagsBits.AF | RflagsBits.CF | RflagsBits.PF + + # xor rdi,5Ah + instr = decoder.decode() + assert instr.rflags_read == RflagsBits.NONE + assert instr.rflags_written == RflagsBits.SF | RflagsBits.ZF | RflagsBits.PF + assert instr.rflags_cleared == RflagsBits.OF | RflagsBits.CF + assert instr.rflags_set == RflagsBits.NONE + assert instr.rflags_undefined == RflagsBits.AF + assert instr.rflags_modified == RflagsBits.OF | RflagsBits.SF | RflagsBits.ZF | RflagsBits.AF | RflagsBits.CF | RflagsBits.PF + ``` + """ + ... @property - def rflags_set(self) -> RflagsBits: ... + def rflags_set(self) -> RflagsBits: + """ + `RflagsBits`: All flags that are always set by the CPU. + + This method returns a `RflagsBits` value. See also `Instruction.rflags_modified`. + + ### Examples: + + ```python + from iced_x86 import * + + # adc rsi,rcx + # xor rdi,5Ah + data = b"\\x48\\x11\\xCE\\x48\\x83\\xF7\\x5A" + decoder = Decoder(64, data) + + # adc rsi,rcx + instr = decoder.decode() + assert instr.rflags_read == RflagsBits.CF + assert instr.rflags_written == RflagsBits.OF | RflagsBits.SF | RflagsBits.ZF | RflagsBits.AF | RflagsBits.CF | RflagsBits.PF + assert instr.rflags_cleared == RflagsBits.NONE + assert instr.rflags_set == RflagsBits.NONE + assert instr.rflags_undefined == RflagsBits.NONE + assert instr.rflags_modified == RflagsBits.OF | RflagsBits.SF | RflagsBits.ZF | RflagsBits.AF | RflagsBits.CF | RflagsBits.PF + + # xor rdi,5Ah + instr = decoder.decode() + assert instr.rflags_read == RflagsBits.NONE + assert instr.rflags_written == RflagsBits.SF | RflagsBits.ZF | RflagsBits.PF + assert instr.rflags_cleared == RflagsBits.OF | RflagsBits.CF + assert instr.rflags_set == RflagsBits.NONE + assert instr.rflags_undefined == RflagsBits.AF + assert instr.rflags_modified == RflagsBits.OF | RflagsBits.SF | RflagsBits.ZF | RflagsBits.AF | RflagsBits.CF | RflagsBits.PF + ``` + """ + ... @property - def rflags_undefined(self) -> RflagsBits: ... + def rflags_undefined(self) -> RflagsBits: + """ + `RflagsBits`: All flags that are undefined after executing the instruction. + + This method returns a `RflagsBits` value. See also `Instruction.rflags_modified`. + + ### Examples: + + ```python + from iced_x86 import * + + # adc rsi,rcx + # xor rdi,5Ah + data = b"\\x48\\x11\\xCE\\x48\\x83\\xF7\\x5A" + decoder = Decoder(64, data) + + # adc rsi,rcx + instr = decoder.decode() + assert instr.rflags_read == RflagsBits.CF + assert instr.rflags_written == RflagsBits.OF | RflagsBits.SF | RflagsBits.ZF | RflagsBits.AF | RflagsBits.CF | RflagsBits.PF + assert instr.rflags_cleared == RflagsBits.NONE + assert instr.rflags_set == RflagsBits.NONE + assert instr.rflags_undefined == RflagsBits.NONE + assert instr.rflags_modified == RflagsBits.OF | RflagsBits.SF | RflagsBits.ZF | RflagsBits.AF | RflagsBits.CF | RflagsBits.PF + + # xor rdi,5Ah + instr = decoder.decode() + assert instr.rflags_read == RflagsBits.NONE + assert instr.rflags_written == RflagsBits.SF | RflagsBits.ZF | RflagsBits.PF + assert instr.rflags_cleared == RflagsBits.OF | RflagsBits.CF + assert instr.rflags_set == RflagsBits.NONE + assert instr.rflags_undefined == RflagsBits.AF + assert instr.rflags_modified == RflagsBits.OF | RflagsBits.SF | RflagsBits.ZF | RflagsBits.AF | RflagsBits.CF | RflagsBits.PF + ``` + """ + ... @property - def rflags_modified(self) -> RflagsBits: ... + def rflags_modified(self) -> RflagsBits: + """ + `RflagsBits`: All flags that are modified by the CPU. This is `rflags_written + rflags_cleared + rflags_set + rflags_undefined`. + + This method returns a `RflagsBits` value. + + ### Examples: + + ```python + from iced_x86 import * + + # adc rsi,rcx + # xor rdi,5Ah + data = b"\\x48\\x11\\xCE\\x48\\x83\\xF7\\x5A" + decoder = Decoder(64, data) + + # adc rsi,rcx + instr = decoder.decode() + assert instr.rflags_read == RflagsBits.CF + assert instr.rflags_written == RflagsBits.OF | RflagsBits.SF | RflagsBits.ZF | RflagsBits.AF | RflagsBits.CF | RflagsBits.PF + assert instr.rflags_cleared == RflagsBits.NONE + assert instr.rflags_set == RflagsBits.NONE + assert instr.rflags_undefined == RflagsBits.NONE + assert instr.rflags_modified == RflagsBits.OF | RflagsBits.SF | RflagsBits.ZF | RflagsBits.AF | RflagsBits.CF | RflagsBits.PF + + # xor rdi,5Ah + instr = decoder.decode() + assert instr.rflags_read == RflagsBits.NONE + assert instr.rflags_written == RflagsBits.SF | RflagsBits.ZF | RflagsBits.PF + assert instr.rflags_cleared == RflagsBits.OF | RflagsBits.CF + assert instr.rflags_set == RflagsBits.NONE + assert instr.rflags_undefined == RflagsBits.AF + assert instr.rflags_modified == RflagsBits.OF | RflagsBits.SF | RflagsBits.ZF | RflagsBits.AF | RflagsBits.CF | RflagsBits.PF + ``` + """ + ... @property - def is_jcc_short_or_near(self) -> bool: ... + def is_jcc_short_or_near(self) -> bool: + """bool: Checks if it's a `Jcc SHORT` or `Jcc NEAR` instruction""" + ... @property - def is_jcc_near(self) -> bool: ... + def is_jcc_near(self) -> bool: + """bool: Checks if it's a `Jcc NEAR` instruction""" + ... @property - def is_jcc_short(self) -> bool: ... + def is_jcc_short(self) -> bool: + """bool: Checks if it's a `Jcc SHORT` instruction""" + ... @property - def is_jmp_short(self) -> bool: ... + def is_jmp_short(self) -> bool: + """bool: Checks if it's a `JMP SHORT` instruction""" + ... @property - def is_jmp_near(self) -> bool: ... + def is_jmp_near(self) -> bool: + """bool: Checks if it's a `JMP NEAR` instruction""" + ... @property - def is_jmp_short_or_near(self) -> bool: ... + def is_jmp_short_or_near(self) -> bool: + """bool: Checks if it's a `JMP SHORT` or a `JMP NEAR` instruction""" + ... @property - def is_jmp_far(self) -> bool: ... + def is_jmp_far(self) -> bool: + """bool: Checks if it's a `JMP FAR` instruction""" + ... @property - def is_call_near(self) -> bool: ... + def is_call_near(self) -> bool: + """bool: Checks if it's a `CALL NEAR` instruction""" + ... @property - def is_call_far(self) -> bool: ... + def is_call_far(self) -> bool: + """bool: Checks if it's a `CALL FAR` instruction""" + ... @property - def is_jmp_near_indirect(self) -> bool: ... + def is_jmp_near_indirect(self) -> bool: + """bool: Checks if it's a `JMP NEAR reg/[mem]` instruction""" + ... @property - def is_jmp_far_indirect(self) -> bool: ... + def is_jmp_far_indirect(self) -> bool: + """bool: Checks if it's a `JMP FAR [mem]` instruction""" + ... @property - def is_call_near_indirect(self) -> bool: ... + def is_call_near_indirect(self) -> bool: + """bool: Checks if it's a `CALL NEAR reg/[mem]` instruction""" + ... @property - def is_call_far_indirect(self) -> bool: ... - def negate_condition_code(self) -> None: ... - def as_short_branch(self) -> None: ... - def as_near_branch(self) -> None: ... + def is_call_far_indirect(self) -> bool: + """bool: Checks if it's a `CALL FAR [mem]` instruction""" + ... + def negate_condition_code(self) -> None: + """ + Negates the condition code, eg. `JE` -> `JNE`. + + Can be used if it's `Jcc`, `SETcc`, `CMOVcc`, `LOOPcc` and does nothing if the instruction doesn't have a condition code. + + ### Examples: + + ```python + from iced_x86 import * + + # setbe al + data = b"\\x0F\\x96\\xC0" + decoder = Decoder(64, data) + + instr = decoder.decode() + assert instr.code == Code.SETBE_RM8 + assert instr.condition_code == ConditionCode.BE + instr.negate_condition_code() + assert instr.code == Code.SETA_RM8 + assert instr.condition_code == ConditionCode.A + ``` + """ + ... + def as_short_branch(self) -> None: + """ + Converts `Jcc/JMP NEAR` to `Jcc/JMP SHORT` and does nothing if it's not a `Jcc/JMP NEAR` instruction + + ### Examples: + + ```python + from iced_x86 import * + + # jbe near ptr label + data = b"\\x0F\\x86\\x5A\\xA5\\x12\\x34" + decoder = Decoder(64, data) + + instr = decoder.decode() + assert instr.code == Code.JBE_REL32_64 + instr.as_short_branch() + assert instr.code == Code.JBE_REL8_64 + instr.as_short_branch() + assert instr.code == Code.JBE_REL8_64 + ``` + """ + ... + def as_near_branch(self) -> None: + """ + Converts `Jcc/JMP SHORT` to `Jcc/JMP NEAR` and does nothing if it's not a `Jcc/JMP SHORT` instruction + + ### Examples: + + ```python + from iced_x86 import * + + # jbe short label + data = b"\\x76\\x5A" + decoder = Decoder(64, data) + + instr = decoder.decode() + assert instr.code == Code.JBE_REL8_64 + instr.as_near_branch() + assert instr.code == Code.JBE_REL32_64 + instr.as_near_branch() + assert instr.code == Code.JBE_REL32_64 + ``` + """ + ... @property - def condition_code(self) -> ConditionCode: ... - def op_code(self) -> OpCodeInfo: ... + def condition_code(self) -> ConditionCode: + """ + `ConditionCode`: Gets the condition code (a `ConditionCode` enum value) if it's `Jcc`, `SETcc`, `CMOVcc`, `LOOPcc` else `ConditionCode.NONE` is returned + + ### Examples: + + ```python + from iced_x86 import * + + # setbe al + # jl short label + # cmovne ecx,esi + # nop + data = b"\\x0F\\x96\\xC0\\x7C\\x5A\\x0F\\x45\\xCE\\x90" + decoder = Decoder(64, data) + + # setbe al + instr = decoder.decode() + assert instr.condition_code == ConditionCode.BE + + # jl short label + instr = decoder.decode() + assert instr.condition_code == ConditionCode.L + + # cmovne ecx,esi + instr = decoder.decode() + assert instr.condition_code == ConditionCode.NE + + # nop + instr = decoder.decode() + assert instr.condition_code == ConditionCode.NONE + ``` + """ + ... + def op_code(self) -> OpCodeInfo: + """ + Gets the `OpCodeInfo` + + ### Returns: + + - `OpCodeInfo`: Op code info + """ + ... def __repr__(self) -> str: ... def __str__(self) -> str: ... def __format__(self, format_spec: str) -> str: ... @@ -686,828 +2597,6224 @@ class Instruction: def __bool__(self) -> bool: ... def __len__(self) -> int: ... @staticmethod - def create(code: Code) -> Instruction: ... - @staticmethod - def create_reg(code: Code, register: Register) -> Instruction: ... - @staticmethod - def create_i32(code: Code, immediate: int) -> Instruction: ... - @staticmethod - def create_u32(code: Code, immediate: int) -> Instruction: ... - @staticmethod - def create_mem(code: Code, memory: MemoryOperand) -> Instruction: ... - @staticmethod - def create_reg_reg(code: Code, register1: Register, register2: Register) -> Instruction: ... - @staticmethod - def create_reg_i32(code: Code, register: Register, immediate: int) -> Instruction: ... - @staticmethod - def create_reg_u32(code: Code, register: Register, immediate: int) -> Instruction: ... - @staticmethod - def create_reg_i64(code: Code, register: Register, immediate: int) -> Instruction: ... - @staticmethod - def create_reg_u64(code: Code, register: Register, immediate: int) -> Instruction: ... - @staticmethod - def create_reg_mem(code: Code, register: Register, memory: MemoryOperand) -> Instruction: ... - @staticmethod - def create_i32_reg(code: Code, immediate: int, register: Register) -> Instruction: ... - @staticmethod - def create_u32_reg(code: Code, immediate: int, register: Register) -> Instruction: ... - @staticmethod - def create_i32_i32(code: Code, immediate1: int, immediate2: int) -> Instruction: ... - @staticmethod - def create_u32_u32(code: Code, immediate1: int, immediate2: int) -> Instruction: ... - @staticmethod - def create_mem_reg(code: Code, memory: MemoryOperand, register: Register) -> Instruction: ... - @staticmethod - def create_mem_i32(code: Code, memory: MemoryOperand, immediate: int) -> Instruction: ... - @staticmethod - def create_mem_u32(code: Code, memory: MemoryOperand, immediate: int) -> Instruction: ... - @staticmethod - def create_reg_reg_reg(code: Code, register1: Register, register2: Register, register3: Register) -> Instruction: ... - @staticmethod - def create_reg_reg_i32(code: Code, register1: Register, register2: Register, immediate: int) -> Instruction: ... - @staticmethod - def create_reg_reg_u32(code: Code, register1: Register, register2: Register, immediate: int) -> Instruction: ... - @staticmethod - def create_reg_reg_mem(code: Code, register1: Register, register2: Register, memory: MemoryOperand) -> Instruction: ... - @staticmethod - def create_reg_i32_i32(code: Code, register: Register, immediate1: int, immediate2: int) -> Instruction: ... - @staticmethod - def create_reg_u32_u32(code: Code, register: Register, immediate1: int, immediate2: int) -> Instruction: ... - @staticmethod - def create_reg_mem_reg(code: Code, register1: Register, memory: MemoryOperand, register2: Register) -> Instruction: ... - @staticmethod - def create_reg_mem_i32(code: Code, register: Register, memory: MemoryOperand, immediate: int) -> Instruction: ... - @staticmethod - def create_reg_mem_u32(code: Code, register: Register, memory: MemoryOperand, immediate: int) -> Instruction: ... - @staticmethod - def create_mem_reg_reg(code: Code, memory: MemoryOperand, register1: Register, register2: Register) -> Instruction: ... - @staticmethod - def create_mem_reg_i32(code: Code, memory: MemoryOperand, register: Register, immediate: int) -> Instruction: ... - @staticmethod - def create_mem_reg_u32(code: Code, memory: MemoryOperand, register: Register, immediate: int) -> Instruction: ... - @staticmethod - def create_reg_reg_reg_reg(code: Code, register1: Register, register2: Register, register3: Register, register4: Register) -> Instruction: ... - @staticmethod - def create_reg_reg_reg_i32(code: Code, register1: Register, register2: Register, register3: Register, immediate: int) -> Instruction: ... - @staticmethod - def create_reg_reg_reg_u32(code: Code, register1: Register, register2: Register, register3: Register, immediate: int) -> Instruction: ... - @staticmethod - def create_reg_reg_reg_mem(code: Code, register1: Register, register2: Register, register3: Register, memory: MemoryOperand) -> Instruction: ... - @staticmethod - def create_reg_reg_i32_i32(code: Code, register1: Register, register2: Register, immediate1: int, immediate2: int) -> Instruction: ... - @staticmethod - def create_reg_reg_u32_u32(code: Code, register1: Register, register2: Register, immediate1: int, immediate2: int) -> Instruction: ... - @staticmethod - def create_reg_reg_mem_reg(code: Code, register1: Register, register2: Register, memory: MemoryOperand, register3: Register) -> Instruction: ... - @staticmethod - def create_reg_reg_mem_i32(code: Code, register1: Register, register2: Register, memory: MemoryOperand, immediate: int) -> Instruction: ... - @staticmethod - def create_reg_reg_mem_u32(code: Code, register1: Register, register2: Register, memory: MemoryOperand, immediate: int) -> Instruction: ... - @staticmethod - def create_reg_reg_reg_reg_i32(code: Code, register1: Register, register2: Register, register3: Register, register4: Register, immediate: int) -> Instruction: ... - @staticmethod - def create_reg_reg_reg_reg_u32(code: Code, register1: Register, register2: Register, register3: Register, register4: Register, immediate: int) -> Instruction: ... - @staticmethod - def create_reg_reg_reg_mem_i32(code: Code, register1: Register, register2: Register, register3: Register, memory: MemoryOperand, immediate: int) -> Instruction: ... - @staticmethod - def create_reg_reg_reg_mem_u32(code: Code, register1: Register, register2: Register, register3: Register, memory: MemoryOperand, immediate: int) -> Instruction: ... - @staticmethod - def create_reg_reg_mem_reg_i32(code: Code, register1: Register, register2: Register, memory: MemoryOperand, register3: Register, immediate: int) -> Instruction: ... - @staticmethod - def create_reg_reg_mem_reg_u32(code: Code, register1: Register, register2: Register, memory: MemoryOperand, register3: Register, immediate: int) -> Instruction: ... - @staticmethod - def create_branch(code: Code, target: int) -> Instruction: ... - @staticmethod - def create_far_branch(code: Code, selector: int, offset: int) -> Instruction: ... - @staticmethod - def create_xbegin(bitness: int, target: int) -> Instruction: ... - @staticmethod - def create_reg_mem64(code: Code, register: Register, address: int, segment_prefix: Register = Register.NONE) -> Instruction: ... - @staticmethod - def create_mem64_reg(code: Code, address: int, register: Register, segment_prefix: Register = Register.NONE) -> Instruction: ... - @staticmethod - def create_outsb(address_size: int, segment_prefix: Register = Register.NONE, rep_prefix: RepPrefixKind = RepPrefixKind.NONE) -> Instruction: ... - @staticmethod - def create_rep_outsb(address_size: int) -> Instruction: ... - @staticmethod - def create_outsw(address_size: int, segment_prefix: Register = Register.NONE, rep_prefix: RepPrefixKind = RepPrefixKind.NONE) -> Instruction: ... - @staticmethod - def create_rep_outsw(address_size: int) -> Instruction: ... - @staticmethod - def create_outsd(address_size: int, segment_prefix: Register = Register.NONE, rep_prefix: RepPrefixKind = RepPrefixKind.NONE) -> Instruction: ... - @staticmethod - def create_rep_outsd(address_size: int) -> Instruction: ... - @staticmethod - def create_lodsb(address_size: int, segment_prefix: Register = Register.NONE, rep_prefix: RepPrefixKind = RepPrefixKind.NONE) -> Instruction: ... - @staticmethod - def create_rep_lodsb(address_size: int) -> Instruction: ... - @staticmethod - def create_lodsw(address_size: int, segment_prefix: Register = Register.NONE, rep_prefix: RepPrefixKind = RepPrefixKind.NONE) -> Instruction: ... - @staticmethod - def create_rep_lodsw(address_size: int) -> Instruction: ... - @staticmethod - def create_lodsd(address_size: int, segment_prefix: Register = Register.NONE, rep_prefix: RepPrefixKind = RepPrefixKind.NONE) -> Instruction: ... - @staticmethod - def create_rep_lodsd(address_size: int) -> Instruction: ... - @staticmethod - def create_lodsq(address_size: int, segment_prefix: Register = Register.NONE, rep_prefix: RepPrefixKind = RepPrefixKind.NONE) -> Instruction: ... - @staticmethod - def create_rep_lodsq(address_size: int) -> Instruction: ... - @staticmethod - def create_scasb(address_size: int, rep_prefix: RepPrefixKind = RepPrefixKind.NONE) -> Instruction: ... - @staticmethod - def create_repe_scasb(address_size: int) -> Instruction: ... - @staticmethod - def create_repne_scasb(address_size: int) -> Instruction: ... - @staticmethod - def create_scasw(address_size: int, rep_prefix: RepPrefixKind = RepPrefixKind.NONE) -> Instruction: ... - @staticmethod - def create_repe_scasw(address_size: int) -> Instruction: ... - @staticmethod - def create_repne_scasw(address_size: int) -> Instruction: ... - @staticmethod - def create_scasd(address_size: int, rep_prefix: RepPrefixKind = RepPrefixKind.NONE) -> Instruction: ... - @staticmethod - def create_repe_scasd(address_size: int) -> Instruction: ... - @staticmethod - def create_repne_scasd(address_size: int) -> Instruction: ... - @staticmethod - def create_scasq(address_size: int, rep_prefix: RepPrefixKind = RepPrefixKind.NONE) -> Instruction: ... - @staticmethod - def create_repe_scasq(address_size: int) -> Instruction: ... - @staticmethod - def create_repne_scasq(address_size: int) -> Instruction: ... - @staticmethod - def create_insb(address_size: int, rep_prefix: RepPrefixKind = RepPrefixKind.NONE) -> Instruction: ... - @staticmethod - def create_rep_insb(address_size: int) -> Instruction: ... - @staticmethod - def create_insw(address_size: int, rep_prefix: RepPrefixKind = RepPrefixKind.NONE) -> Instruction: ... - @staticmethod - def create_rep_insw(address_size: int) -> Instruction: ... - @staticmethod - def create_insd(address_size: int, rep_prefix: RepPrefixKind = RepPrefixKind.NONE) -> Instruction: ... - @staticmethod - def create_rep_insd(address_size: int) -> Instruction: ... - @staticmethod - def create_stosb(address_size: int, rep_prefix: RepPrefixKind = RepPrefixKind.NONE) -> Instruction: ... - @staticmethod - def create_rep_stosb(address_size: int) -> Instruction: ... - @staticmethod - def create_stosw(address_size: int, rep_prefix: RepPrefixKind = RepPrefixKind.NONE) -> Instruction: ... - @staticmethod - def create_rep_stosw(address_size: int) -> Instruction: ... - @staticmethod - def create_stosd(address_size: int, rep_prefix: RepPrefixKind = RepPrefixKind.NONE) -> Instruction: ... - @staticmethod - def create_rep_stosd(address_size: int) -> Instruction: ... - @staticmethod - def create_stosq(address_size: int, rep_prefix: RepPrefixKind = RepPrefixKind.NONE) -> Instruction: ... - @staticmethod - def create_rep_stosq(address_size: int) -> Instruction: ... - @staticmethod - def create_cmpsb(address_size: int, segment_prefix: Register = Register.NONE, rep_prefix: RepPrefixKind = RepPrefixKind.NONE) -> Instruction: ... - @staticmethod - def create_repe_cmpsb(address_size: int) -> Instruction: ... - @staticmethod - def create_repne_cmpsb(address_size: int) -> Instruction: ... - @staticmethod - def create_cmpsw(address_size: int, segment_prefix: Register = Register.NONE, rep_prefix: RepPrefixKind = RepPrefixKind.NONE) -> Instruction: ... - @staticmethod - def create_repe_cmpsw(address_size: int) -> Instruction: ... - @staticmethod - def create_repne_cmpsw(address_size: int) -> Instruction: ... - @staticmethod - def create_cmpsd(address_size: int, segment_prefix: Register = Register.NONE, rep_prefix: RepPrefixKind = RepPrefixKind.NONE) -> Instruction: ... - @staticmethod - def create_repe_cmpsd(address_size: int) -> Instruction: ... - @staticmethod - def create_repne_cmpsd(address_size: int) -> Instruction: ... - @staticmethod - def create_cmpsq(address_size: int, segment_prefix: Register = Register.NONE, rep_prefix: RepPrefixKind = RepPrefixKind.NONE) -> Instruction: ... - @staticmethod - def create_repe_cmpsq(address_size: int) -> Instruction: ... - @staticmethod - def create_repne_cmpsq(address_size: int) -> Instruction: ... - @staticmethod - def create_movsb(address_size: int, segment_prefix: Register = Register.NONE, rep_prefix: RepPrefixKind = RepPrefixKind.NONE) -> Instruction: ... - @staticmethod - def create_rep_movsb(address_size: int) -> Instruction: ... - @staticmethod - def create_movsw(address_size: int, segment_prefix: Register = Register.NONE, rep_prefix: RepPrefixKind = RepPrefixKind.NONE) -> Instruction: ... - @staticmethod - def create_rep_movsw(address_size: int) -> Instruction: ... - @staticmethod - def create_movsd(address_size: int, segment_prefix: Register = Register.NONE, rep_prefix: RepPrefixKind = RepPrefixKind.NONE) -> Instruction: ... - @staticmethod - def create_rep_movsd(address_size: int) -> Instruction: ... - @staticmethod - def create_movsq(address_size: int, segment_prefix: Register = Register.NONE, rep_prefix: RepPrefixKind = RepPrefixKind.NONE) -> Instruction: ... - @staticmethod - def create_rep_movsq(address_size: int) -> Instruction: ... - @staticmethod - def create_maskmovq(address_size: int, register1: Register, register2: Register, segment_prefix: Register = Register.NONE) -> Instruction: ... - @staticmethod - def create_maskmovdqu(address_size: int, register1: Register, register2: Register, segment_prefix: Register = Register.NONE) -> Instruction: ... - @staticmethod - def create_vmaskmovdqu(address_size: int, register1: Register, register2: Register, segment_prefix: Register = Register.NONE) -> Instruction: ... - @staticmethod - def create_declare_byte_1(b0: int) -> Instruction: ... - @staticmethod - def create_declare_byte_2(b0: int, b1: int) -> Instruction: ... - @staticmethod - def create_declare_byte_3(b0: int, b1: int, b2: int) -> Instruction: ... - @staticmethod - def create_declare_byte_4(b0: int, b1: int, b2: int, b3: int) -> Instruction: ... - @staticmethod - def create_declare_byte_5(b0: int, b1: int, b2: int, b3: int, b4: int) -> Instruction: ... - @staticmethod - def create_declare_byte_6(b0: int, b1: int, b2: int, b3: int, b4: int, b5: int) -> Instruction: ... - @staticmethod - def create_declare_byte_7(b0: int, b1: int, b2: int, b3: int, b4: int, b5: int, b6: int) -> Instruction: ... - @staticmethod - def create_declare_byte_8(b0: int, b1: int, b2: int, b3: int, b4: int, b5: int, b6: int, b7: int) -> Instruction: ... - @staticmethod - def create_declare_byte_9(b0: int, b1: int, b2: int, b3: int, b4: int, b5: int, b6: int, b7: int, b8: int) -> Instruction: ... - @staticmethod - def create_declare_byte_10(b0: int, b1: int, b2: int, b3: int, b4: int, b5: int, b6: int, b7: int, b8: int, b9: int) -> Instruction: ... - @staticmethod - def create_declare_byte_11(b0: int, b1: int, b2: int, b3: int, b4: int, b5: int, b6: int, b7: int, b8: int, b9: int, b10: int) -> Instruction: ... - @staticmethod - def create_declare_byte_12(b0: int, b1: int, b2: int, b3: int, b4: int, b5: int, b6: int, b7: int, b8: int, b9: int, b10: int, b11: int) -> Instruction: ... - @staticmethod - def create_declare_byte_13(b0: int, b1: int, b2: int, b3: int, b4: int, b5: int, b6: int, b7: int, b8: int, b9: int, b10: int, b11: int, b12: int) -> Instruction: ... - @staticmethod - def create_declare_byte_14(b0: int, b1: int, b2: int, b3: int, b4: int, b5: int, b6: int, b7: int, b8: int, b9: int, b10: int, b11: int, b12: int, b13: int) -> Instruction: ... - @staticmethod - def create_declare_byte_15(b0: int, b1: int, b2: int, b3: int, b4: int, b5: int, b6: int, b7: int, b8: int, b9: int, b10: int, b11: int, b12: int, b13: int, b14: int) -> Instruction: ... - @staticmethod - def create_declare_byte_16(b0: int, b1: int, b2: int, b3: int, b4: int, b5: int, b6: int, b7: int, b8: int, b9: int, b10: int, b11: int, b12: int, b13: int, b14: int, b15: int) -> Instruction: ... - @staticmethod - def create_declare_byte(data: Union[bytes, bytearray]) -> Instruction: ... - @staticmethod - def create_declare_word_1(w0: int) -> Instruction: ... - @staticmethod - def create_declare_word_2(w0: int, w1: int) -> Instruction: ... - @staticmethod - def create_declare_word_3(w0: int, w1: int, w2: int) -> Instruction: ... - @staticmethod - def create_declare_word_4(w0: int, w1: int, w2: int, w3: int) -> Instruction: ... - @staticmethod - def create_declare_word_5(w0: int, w1: int, w2: int, w3: int, w4: int) -> Instruction: ... - @staticmethod - def create_declare_word_6(w0: int, w1: int, w2: int, w3: int, w4: int, w5: int) -> Instruction: ... - @staticmethod - def create_declare_word_7(w0: int, w1: int, w2: int, w3: int, w4: int, w5: int, w6: int) -> Instruction: ... - @staticmethod - def create_declare_word_8(w0: int, w1: int, w2: int, w3: int, w4: int, w5: int, w6: int, w7: int) -> Instruction: ... - @staticmethod - def create_declare_dword_1(d0: int) -> Instruction: ... - @staticmethod - def create_declare_dword_2(d0: int, d1: int) -> Instruction: ... - @staticmethod - def create_declare_dword_3(d0: int, d1: int, d2: int) -> Instruction: ... - @staticmethod - def create_declare_dword_4(d0: int, d1: int, d2: int, d3: int) -> Instruction: ... - @staticmethod - def create_declare_qword_1(q0: int) -> Instruction: ... - @staticmethod - def create_declare_qword_2(q0: int, q1: int) -> Instruction: ... + def create(code: Code) -> Instruction: + """ + Creates an instruction with no operands + + ### Args: + + - `code` (`Code`): Code value + + ### Returns: + + - `Instruction`: Created instruction + """ + ... + @staticmethod + def create_reg(code: Code, register: Register) -> Instruction: + """ + Creates an instruction with 1 operand + + ### Args: + + - `code` (`Code`): Code value + - `register` (`Register`): op0: Register + + ### Returns: + + - `Instruction`: Created instruction + """ + ... + @staticmethod + def create_i32(code: Code, immediate: int) -> Instruction: + """ + Creates an instruction with 1 operand + + ### Args: + + - `code` (`Code`): Code value + - `immediate` (int): (`i32`) op0: Immediate value + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If the immediate is invalid + """ + ... + @staticmethod + def create_u32(code: Code, immediate: int) -> Instruction: + """ + Creates an instruction with 1 operand + + ### Args: + + - `code` (`Code`): Code value + - `immediate` (int): (`u32`) op0: Immediate value + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If the immediate is invalid + """ + ... + @staticmethod + def create_mem(code: Code, memory: MemoryOperand) -> Instruction: + """ + Creates an instruction with 1 operand + + ### Args: + + - `code` (`Code`): Code value + - `memory` (`MemoryOperand`): op0: Memory operand + + ### Returns: + + - `Instruction`: Created instruction + """ + ... + @staticmethod + def create_reg_reg(code: Code, register1: Register, register2: Register) -> Instruction: + """ + Creates an instruction with 2 operands + + ### Args: + + - `code` (`Code`): Code value + - `register1` (`Register`): op0: Register + - `register2` (`Register`): op1: Register + + ### Returns: + + - `Instruction`: Created instruction + """ + ... + @staticmethod + def create_reg_i32(code: Code, register: Register, immediate: int) -> Instruction: + """ + Creates an instruction with 2 operands + + ### Args: + + - `code` (`Code`): Code value + - `register` (`Register`): op0: Register + - `immediate` (int): (`i32`) op1: Immediate value + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If the immediate is invalid + """ + ... + @staticmethod + def create_reg_u32(code: Code, register: Register, immediate: int) -> Instruction: + """ + Creates an instruction with 2 operands + + ### Args: + + - `code` (`Code`): Code value + - `register` (`Register`): op0: Register + - `immediate` (int): (`u32`) op1: Immediate value + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If the immediate is invalid + """ + ... + @staticmethod + def create_reg_i64(code: Code, register: Register, immediate: int) -> Instruction: + """ + Creates an instruction with 2 operands + + ### Args: + + - `code` (`Code`): Code value + - `register` (`Register`): op0: Register + - `immediate` (int): (`i64`) op1: Immediate value + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If the immediate is invalid + """ + ... + @staticmethod + def create_reg_u64(code: Code, register: Register, immediate: int) -> Instruction: + """ + Creates an instruction with 2 operands + + ### Args: + + - `code` (`Code`): Code value + - `register` (`Register`): op0: Register + - `immediate` (int): (`u64`) op1: Immediate value + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If the immediate is invalid + """ + ... + @staticmethod + def create_reg_mem(code: Code, register: Register, memory: MemoryOperand) -> Instruction: + """ + Creates an instruction with 2 operands + + ### Args: + + - `code` (`Code`): Code value + - `register` (`Register`): op0: Register + - `memory` (`MemoryOperand`): op1: Memory operand + + ### Returns: + + - `Instruction`: Created instruction + """ + ... + @staticmethod + def create_i32_reg(code: Code, immediate: int, register: Register) -> Instruction: + """ + Creates an instruction with 2 operands + + ### Args: + + - `code` (`Code`): Code value + - `immediate` (int): (`i32`) op0: Immediate value + - `register` (`Register`): op1: Register + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If the immediate is invalid + """ + ... + @staticmethod + def create_u32_reg(code: Code, immediate: int, register: Register) -> Instruction: + """ + Creates an instruction with 2 operands + + ### Args: + + - `code` (`Code`): Code value + - `immediate` (int): (`u32`) op0: Immediate value + - `register` (`Register`): op1: Register + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If the immediate is invalid + """ + ... + @staticmethod + def create_i32_i32(code: Code, immediate1: int, immediate2: int) -> Instruction: + """ + Creates an instruction with 2 operands + + ### Args: + + - `code` (`Code`): Code value + - `immediate1` (int): (`i32`) op0: Immediate value + - `immediate2` (int): (`i32`) op1: Immediate value + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If the immediate is invalid + """ + ... + @staticmethod + def create_u32_u32(code: Code, immediate1: int, immediate2: int) -> Instruction: + """ + Creates an instruction with 2 operands + + ### Args: + + - `code` (`Code`): Code value + - `immediate1` (int): (`u32`) op0: Immediate value + - `immediate2` (int): (`u32`) op1: Immediate value + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If the immediate is invalid + """ + ... + @staticmethod + def create_mem_reg(code: Code, memory: MemoryOperand, register: Register) -> Instruction: + """ + Creates an instruction with 2 operands + + ### Args: + + - `code` (`Code`): Code value + - `memory` (`MemoryOperand`): op0: Memory operand + - `register` (`Register`): op1: Register + + ### Returns: + + - `Instruction`: Created instruction + """ + ... + @staticmethod + def create_mem_i32(code: Code, memory: MemoryOperand, immediate: int) -> Instruction: + """ + Creates an instruction with 2 operands + + ### Args: + + - `code` (`Code`): Code value + - `memory` (`MemoryOperand`): op0: Memory operand + - `immediate` (int): (`i32`) op1: Immediate value + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If the immediate is invalid + """ + ... + @staticmethod + def create_mem_u32(code: Code, memory: MemoryOperand, immediate: int) -> Instruction: + """ + Creates an instruction with 2 operands + + ### Args: + + - `code` (`Code`): Code value + - `memory` (`MemoryOperand`): op0: Memory operand + - `immediate` (int): (`u32`) op1: Immediate value + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If the immediate is invalid + """ + ... + @staticmethod + def create_reg_reg_reg(code: Code, register1: Register, register2: Register, register3: Register) -> Instruction: + """ + Creates an instruction with 3 operands + + ### Args: + + - `code` (`Code`): Code value + - `register1` (`Register`): op0: Register + - `register2` (`Register`): op1: Register + - `register3` (`Register`): op2: Register + + ### Returns: + + - `Instruction`: Created instruction + """ + ... + @staticmethod + def create_reg_reg_i32(code: Code, register1: Register, register2: Register, immediate: int) -> Instruction: + """ + Creates an instruction with 3 operands + + ### Args: + + - `code` (`Code`): Code value + - `register1` (`Register`): op0: Register + - `register2` (`Register`): op1: Register + - `immediate` (int): (`i32`) op2: Immediate value + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If the immediate is invalid + """ + ... + @staticmethod + def create_reg_reg_u32(code: Code, register1: Register, register2: Register, immediate: int) -> Instruction: + """ + Creates an instruction with 3 operands + + ### Args: + + - `code` (`Code`): Code value + - `register1` (`Register`): op0: Register + - `register2` (`Register`): op1: Register + - `immediate` (int): (`u32`) op2: Immediate value + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If the immediate is invalid + """ + ... + @staticmethod + def create_reg_reg_mem(code: Code, register1: Register, register2: Register, memory: MemoryOperand) -> Instruction: + """ + Creates an instruction with 3 operands + + ### Args: + + - `code` (`Code`): Code value + - `register1` (`Register`): op0: Register + - `register2` (`Register`): op1: Register + - `memory` (`MemoryOperand`): op2: Memory operand + + ### Returns: + + - `Instruction`: Created instruction + """ + ... + @staticmethod + def create_reg_i32_i32(code: Code, register: Register, immediate1: int, immediate2: int) -> Instruction: + """ + Creates an instruction with 3 operands + + ### Args: + + - `code` (`Code`): Code value + - `register` (`Register`): op0: Register + - `immediate1` (int): (`i32`) op1: Immediate value + - `immediate2` (int): (`i32`) op2: Immediate value + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If the immediate is invalid + """ + ... + @staticmethod + def create_reg_u32_u32(code: Code, register: Register, immediate1: int, immediate2: int) -> Instruction: + """ + Creates an instruction with 3 operands + + ### Args: + + - `code` (`Code`): Code value + - `register` (`Register`): op0: Register + - `immediate1` (int): (`u32`) op1: Immediate value + - `immediate2` (int): (`u32`) op2: Immediate value + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If the immediate is invalid + """ + ... + @staticmethod + def create_reg_mem_reg(code: Code, register1: Register, memory: MemoryOperand, register2: Register) -> Instruction: + """ + Creates an instruction with 3 operands + + ### Args: + + - `code` (`Code`): Code value + - `register1` (`Register`): op0: Register + - `memory` (`MemoryOperand`): op1: Memory operand + - `register2` (`Register`): op2: Register + + ### Returns: + + - `Instruction`: Created instruction + """ + ... + @staticmethod + def create_reg_mem_i32(code: Code, register: Register, memory: MemoryOperand, immediate: int) -> Instruction: + """ + Creates an instruction with 3 operands + + ### Args: + + - `code` (`Code`): Code value + - `register` (`Register`): op0: Register + - `memory` (`MemoryOperand`): op1: Memory operand + - `immediate` (int): (`i32`) op2: Immediate value + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If the immediate is invalid + """ + ... + @staticmethod + def create_reg_mem_u32(code: Code, register: Register, memory: MemoryOperand, immediate: int) -> Instruction: + """ + Creates an instruction with 3 operands + + ### Args: + + - `code` (`Code`): Code value + - `register` (`Register`): op0: Register + - `memory` (`MemoryOperand`): op1: Memory operand + - `immediate` (int): (`u32`) op2: Immediate value + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If the immediate is invalid + """ + ... + @staticmethod + def create_mem_reg_reg(code: Code, memory: MemoryOperand, register1: Register, register2: Register) -> Instruction: + """ + Creates an instruction with 3 operands + + ### Args: + + - `code` (`Code`): Code value + - `memory` (`MemoryOperand`): op0: Memory operand + - `register1` (`Register`): op1: Register + - `register2` (`Register`): op2: Register + + ### Returns: + + - `Instruction`: Created instruction + """ + ... + @staticmethod + def create_mem_reg_i32(code: Code, memory: MemoryOperand, register: Register, immediate: int) -> Instruction: + """ + Creates an instruction with 3 operands + + ### Args: + + - `code` (`Code`): Code value + - `memory` (`MemoryOperand`): op0: Memory operand + - `register` (`Register`): op1: Register + - `immediate` (int): (`i32`) op2: Immediate value + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If the immediate is invalid + """ + ... + @staticmethod + def create_mem_reg_u32(code: Code, memory: MemoryOperand, register: Register, immediate: int) -> Instruction: + """ + Creates an instruction with 3 operands + + ### Args: + + - `code` (`Code`): Code value + - `memory` (`MemoryOperand`): op0: Memory operand + - `register` (`Register`): op1: Register + - `immediate` (int): (`u32`) op2: Immediate value + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If the immediate is invalid + """ + ... + @staticmethod + def create_reg_reg_reg_reg(code: Code, register1: Register, register2: Register, register3: Register, register4: Register) -> Instruction: + """ + Creates an instruction with 4 operands + + ### Args: + + - `code` (`Code`): Code value + - `register1` (`Register`): op0: Register + - `register2` (`Register`): op1: Register + - `register3` (`Register`): op2: Register + - `register4` (`Register`): op3: Register + + ### Returns: + + - `Instruction`: Created instruction + """ + ... + @staticmethod + def create_reg_reg_reg_i32(code: Code, register1: Register, register2: Register, register3: Register, immediate: int) -> Instruction: + """ + Creates an instruction with 4 operands + + ### Args: + + - `code` (`Code`): Code value + - `register1` (`Register`): op0: Register + - `register2` (`Register`): op1: Register + - `register3` (`Register`): op2: Register + - `immediate` (int): (`i32`) op3: Immediate value + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If the immediate is invalid + """ + ... + @staticmethod + def create_reg_reg_reg_u32(code: Code, register1: Register, register2: Register, register3: Register, immediate: int) -> Instruction: + """ + Creates an instruction with 4 operands + + ### Args: + + - `code` (`Code`): Code value + - `register1` (`Register`): op0: Register + - `register2` (`Register`): op1: Register + - `register3` (`Register`): op2: Register + - `immediate` (int): (`u32`) op3: Immediate value + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If the immediate is invalid + """ + ... + @staticmethod + def create_reg_reg_reg_mem(code: Code, register1: Register, register2: Register, register3: Register, memory: MemoryOperand) -> Instruction: + """ + Creates an instruction with 4 operands + + ### Args: + + - `code` (`Code`): Code value + - `register1` (`Register`): op0: Register + - `register2` (`Register`): op1: Register + - `register3` (`Register`): op2: Register + - `memory` (`MemoryOperand`): op3: Memory operand + + ### Returns: + + - `Instruction`: Created instruction + """ + ... + @staticmethod + def create_reg_reg_i32_i32(code: Code, register1: Register, register2: Register, immediate1: int, immediate2: int) -> Instruction: + """ + Creates an instruction with 4 operands + + ### Args: + + - `code` (`Code`): Code value + - `register1` (`Register`): op0: Register + - `register2` (`Register`): op1: Register + - `immediate1` (int): (`i32`) op2: Immediate value + - `immediate2` (int): (`i32`) op3: Immediate value + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If the immediate is invalid + """ + ... + @staticmethod + def create_reg_reg_u32_u32(code: Code, register1: Register, register2: Register, immediate1: int, immediate2: int) -> Instruction: + """ + Creates an instruction with 4 operands + + ### Args: + + - `code` (`Code`): Code value + - `register1` (`Register`): op0: Register + - `register2` (`Register`): op1: Register + - `immediate1` (int): (`u32`) op2: Immediate value + - `immediate2` (int): (`u32`) op3: Immediate value + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If the immediate is invalid + """ + ... + @staticmethod + def create_reg_reg_mem_reg(code: Code, register1: Register, register2: Register, memory: MemoryOperand, register3: Register) -> Instruction: + """ + Creates an instruction with 4 operands + + ### Args: + + - `code` (`Code`): Code value + - `register1` (`Register`): op0: Register + - `register2` (`Register`): op1: Register + - `memory` (`MemoryOperand`): op2: Memory operand + - `register3` (`Register`): op3: Register + + ### Returns: + + - `Instruction`: Created instruction + """ + ... + @staticmethod + def create_reg_reg_mem_i32(code: Code, register1: Register, register2: Register, memory: MemoryOperand, immediate: int) -> Instruction: + """ + Creates an instruction with 4 operands + + ### Args: + + - `code` (`Code`): Code value + - `register1` (`Register`): op0: Register + - `register2` (`Register`): op1: Register + - `memory` (`MemoryOperand`): op2: Memory operand + - `immediate` (int): (`i32`) op3: Immediate value + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If the immediate is invalid + """ + ... + @staticmethod + def create_reg_reg_mem_u32(code: Code, register1: Register, register2: Register, memory: MemoryOperand, immediate: int) -> Instruction: + """ + Creates an instruction with 4 operands + + ### Args: + + - `code` (`Code`): Code value + - `register1` (`Register`): op0: Register + - `register2` (`Register`): op1: Register + - `memory` (`MemoryOperand`): op2: Memory operand + - `immediate` (int): (`u32`) op3: Immediate value + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If the immediate is invalid + """ + ... + @staticmethod + def create_reg_reg_reg_reg_i32(code: Code, register1: Register, register2: Register, register3: Register, register4: Register, immediate: int) -> Instruction: + """ + Creates an instruction with 5 operands + + ### Args: + + - `code` (`Code`): Code value + - `register1` (`Register`): op0: Register + - `register2` (`Register`): op1: Register + - `register3` (`Register`): op2: Register + - `register4` (`Register`): op3: Register + - `immediate` (int): (`i32`) op4: Immediate value + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If the immediate is invalid + """ + ... + @staticmethod + def create_reg_reg_reg_reg_u32(code: Code, register1: Register, register2: Register, register3: Register, register4: Register, immediate: int) -> Instruction: + """ + Creates an instruction with 5 operands + + ### Args: + + - `code` (`Code`): Code value + - `register1` (`Register`): op0: Register + - `register2` (`Register`): op1: Register + - `register3` (`Register`): op2: Register + - `register4` (`Register`): op3: Register + - `immediate` (int): (`u32`) op4: Immediate value + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If the immediate is invalid + """ + ... + @staticmethod + def create_reg_reg_reg_mem_i32(code: Code, register1: Register, register2: Register, register3: Register, memory: MemoryOperand, immediate: int) -> Instruction: + """ + Creates an instruction with 5 operands + + ### Args: + + - `code` (`Code`): Code value + - `register1` (`Register`): op0: Register + - `register2` (`Register`): op1: Register + - `register3` (`Register`): op2: Register + - `memory` (`MemoryOperand`): op3: Memory operand + - `immediate` (int): (`i32`) op4: Immediate value + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If the immediate is invalid + """ + ... + @staticmethod + def create_reg_reg_reg_mem_u32(code: Code, register1: Register, register2: Register, register3: Register, memory: MemoryOperand, immediate: int) -> Instruction: + """ + Creates an instruction with 5 operands + + ### Args: + + - `code` (`Code`): Code value + - `register1` (`Register`): op0: Register + - `register2` (`Register`): op1: Register + - `register3` (`Register`): op2: Register + - `memory` (`MemoryOperand`): op3: Memory operand + - `immediate` (int): (`u32`) op4: Immediate value + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If the immediate is invalid + """ + ... + @staticmethod + def create_reg_reg_mem_reg_i32(code: Code, register1: Register, register2: Register, memory: MemoryOperand, register3: Register, immediate: int) -> Instruction: + """ + Creates an instruction with 5 operands + + ### Args: + + - `code` (`Code`): Code value + - `register1` (`Register`): op0: Register + - `register2` (`Register`): op1: Register + - `memory` (`MemoryOperand`): op2: Memory operand + - `register3` (`Register`): op3: Register + - `immediate` (int): (`i32`) op4: Immediate value + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If the immediate is invalid + """ + ... + @staticmethod + def create_reg_reg_mem_reg_u32(code: Code, register1: Register, register2: Register, memory: MemoryOperand, register3: Register, immediate: int) -> Instruction: + """ + Creates an instruction with 5 operands + + ### Args: + + - `code` (`Code`): Code value + - `register1` (`Register`): op0: Register + - `register2` (`Register`): op1: Register + - `memory` (`MemoryOperand`): op2: Memory operand + - `register3` (`Register`): op3: Register + - `immediate` (int): (`u32`) op4: Immediate value + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If the immediate is invalid + """ + ... + @staticmethod + def create_branch(code: Code, target: int) -> Instruction: + """ + Creates a new near/short branch instruction + + ### Args: + + - `code` (`Code`): Code value + - `target` (int): (`u64`) Target address + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If the created instruction doesn't have a near branch operand + """ + ... + @staticmethod + def create_far_branch(code: Code, selector: int, offset: int) -> Instruction: + """ + Creates a new far branch instruction + + ### Args: + + - `code` (`Code`): Code value + - `selector` (int): (`u16`) Selector/segment value + - `offset` (int): (`u32`) Offset + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If the created instruction doesn't have a far branch operand + """ + ... + @staticmethod + def create_xbegin(bitness: int, target: int) -> Instruction: + """ + Creates a new `XBEGIN` instruction + + ### Args: + + - `bitness` (int): (`u32`) 16, 32, or 64 + - `target` (int): (`u64`) Target address + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If `bitness` is not one of 16, 32, 64. + """ + ... + @staticmethod + def create_reg_mem64(code: Code, register: Register, address: int, segment_prefix: Register = Register.NONE) -> Instruction: + """ + Creates an instruction with a 64-bit memory offset as the second operand, eg. `mov al,[123456789ABCDEF0]` + + ### Args: + + - `code` (`Code`): Code value + - `register` (`Register`): Register (`AL`, `AX`, `EAX`, `RAX`) + - `address` (int): (`u64`) 64-bit address + - `segment_prefix` (`Register`): Segment override or `Register.NONE` + + ### Returns: + + - `Instruction`: Created instruction + """ + ... + @staticmethod + def create_mem64_reg(code: Code, address: int, register: Register, segment_prefix: Register = Register.NONE) -> Instruction: + """ + Creates an instruction with a 64-bit memory offset as the first operand, eg. `mov [123456789ABCDEF0],al` + + ### Args: + + - `code` (`Code`): Code value + - `address` (int): (`u64`) 64-bit address + - `register` (`Register`): Register (`AL`, `AX`, `EAX`, `RAX`) + - `segment_prefix` (`Register`): Segment override or `Register.NONE` + + ### Returns: + + - `Instruction`: Created instruction + """ + ... + @staticmethod + def create_outsb(address_size: int, segment_prefix: Register = Register.NONE, rep_prefix: RepPrefixKind = RepPrefixKind.NONE) -> Instruction: + """ + Creates a `OUTSB` instruction + + ### Args: + + - `address_size` (int): (`u32`) 16, 32, or 64 + - `segment_prefix` (`Register`): Segment override or `Register.NONE` + - `rep_prefix` (`RepPrefixKind`): Rep prefix or `RepPrefixKind.NONE` + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If `address_size` is not one of 16, 32, 64. + """ + ... + @staticmethod + def create_rep_outsb(address_size: int) -> Instruction: + """ + Creates a `REP OUTSB` instruction + + ### Args: + + - `address_size` (int): (`u32`) 16, 32, or 64 + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If `address_size` is not one of 16, 32, 64. + """ + ... + @staticmethod + def create_outsw(address_size: int, segment_prefix: Register = Register.NONE, rep_prefix: RepPrefixKind = RepPrefixKind.NONE) -> Instruction: + """ + Creates a `OUTSW` instruction + + ### Args: + + - `address_size` (int): (`u32`) 16, 32, or 64 + - `segment_prefix` (`Register`): Segment override or `Register.NONE` + - `rep_prefix` (`RepPrefixKind`): Rep prefix or `RepPrefixKind.NONE` + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If `address_size` is not one of 16, 32, 64. + """ + ... + @staticmethod + def create_rep_outsw(address_size: int) -> Instruction: + """ + Creates a `REP OUTSW` instruction + + ### Args: + + - `address_size` (int): (`u32`) 16, 32, or 64 + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If `address_size` is not one of 16, 32, 64. + """ + ... + @staticmethod + def create_outsd(address_size: int, segment_prefix: Register = Register.NONE, rep_prefix: RepPrefixKind = RepPrefixKind.NONE) -> Instruction: + """ + Creates a `OUTSD` instruction + + ### Args: + + - `address_size` (int): (`u32`) 16, 32, or 64 + - `segment_prefix` (`Register`): Segment override or `Register.NONE` + - `rep_prefix` (`RepPrefixKind`): Rep prefix or `RepPrefixKind.NONE` + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If `address_size` is not one of 16, 32, 64. + """ + ... + @staticmethod + def create_rep_outsd(address_size: int) -> Instruction: + """ + Creates a `REP OUTSD` instruction + + ### Args: + + - `address_size` (int): (`u32`) 16, 32, or 64 + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If `address_size` is not one of 16, 32, 64. + """ + ... + @staticmethod + def create_lodsb(address_size: int, segment_prefix: Register = Register.NONE, rep_prefix: RepPrefixKind = RepPrefixKind.NONE) -> Instruction: + """ + Creates a `LODSB` instruction + + ### Args: + + - `address_size` (int): (`u32`) 16, 32, or 64 + - `segment_prefix` (`Register`): Segment override or `Register.NONE` + - `rep_prefix` (`RepPrefixKind`): Rep prefix or `RepPrefixKind.NONE` + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If `address_size` is not one of 16, 32, 64. + """ + ... + @staticmethod + def create_rep_lodsb(address_size: int) -> Instruction: + """ + Creates a `REP LODSB` instruction + + ### Args: + + - `address_size` (int): (`u32`) 16, 32, or 64 + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If `address_size` is not one of 16, 32, 64. + """ + ... + @staticmethod + def create_lodsw(address_size: int, segment_prefix: Register = Register.NONE, rep_prefix: RepPrefixKind = RepPrefixKind.NONE) -> Instruction: + """ + Creates a `LODSW` instruction + + ### Args: + + - `address_size` (int): (`u32`) 16, 32, or 64 + - `segment_prefix` (`Register`): Segment override or `Register.NONE` + - `rep_prefix` (`RepPrefixKind`): Rep prefix or `RepPrefixKind.NONE` + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If `address_size` is not one of 16, 32, 64. + """ + ... + @staticmethod + def create_rep_lodsw(address_size: int) -> Instruction: + """ + Creates a `REP LODSW` instruction + + ### Args: + + - `address_size` (int): (`u32`) 16, 32, or 64 + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If `address_size` is not one of 16, 32, 64. + """ + ... + @staticmethod + def create_lodsd(address_size: int, segment_prefix: Register = Register.NONE, rep_prefix: RepPrefixKind = RepPrefixKind.NONE) -> Instruction: + """ + Creates a `LODSD` instruction + + ### Args: + + - `address_size` (int): (`u32`) 16, 32, or 64 + - `segment_prefix` (`Register`): Segment override or `Register.NONE` + - `rep_prefix` (`RepPrefixKind`): Rep prefix or `RepPrefixKind.NONE` + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If `address_size` is not one of 16, 32, 64. + """ + ... + @staticmethod + def create_rep_lodsd(address_size: int) -> Instruction: + """ + Creates a `REP LODSD` instruction + + ### Args: + + - `address_size` (int): (`u32`) 16, 32, or 64 + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If `address_size` is not one of 16, 32, 64. + """ + ... + @staticmethod + def create_lodsq(address_size: int, segment_prefix: Register = Register.NONE, rep_prefix: RepPrefixKind = RepPrefixKind.NONE) -> Instruction: + """ + Creates a `LODSQ` instruction + + ### Args: + + - `address_size` (int): (`u32`) 16, 32, or 64 + - `segment_prefix` (`Register`): Segment override or `Register.NONE` + - `rep_prefix` (`RepPrefixKind`): Rep prefix or `RepPrefixKind.NONE` + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If `address_size` is not one of 16, 32, 64. + """ + ... + @staticmethod + def create_rep_lodsq(address_size: int) -> Instruction: + """ + Creates a `REP LODSQ` instruction + + ### Args: + + - `address_size` (int): (`u32`) 16, 32, or 64 + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If `address_size` is not one of 16, 32, 64. + """ + ... + @staticmethod + def create_scasb(address_size: int, rep_prefix: RepPrefixKind = RepPrefixKind.NONE) -> Instruction: + """ + Creates a `SCASB` instruction + + ### Args: + + - `address_size` (int): (`u32`) 16, 32, or 64 + - `rep_prefix` (`RepPrefixKind`): Rep prefix or `RepPrefixKind.NONE` + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If `address_size` is not one of 16, 32, 64. + """ + ... + @staticmethod + def create_repe_scasb(address_size: int) -> Instruction: + """ + Creates a `REPE SCASB` instruction + + ### Args: + + - `address_size` (int): (`u32`) 16, 32, or 64 + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If `address_size` is not one of 16, 32, 64. + """ + ... + @staticmethod + def create_repne_scasb(address_size: int) -> Instruction: + """ + Creates a `REPNE SCASB` instruction + + ### Args: + + - `address_size` (int): (`u32`) 16, 32, or 64 + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If `address_size` is not one of 16, 32, 64. + """ + ... + @staticmethod + def create_scasw(address_size: int, rep_prefix: RepPrefixKind = RepPrefixKind.NONE) -> Instruction: + """ + Creates a `SCASW` instruction + + ### Args: + + - `address_size` (int): (`u32`) 16, 32, or 64 + - `rep_prefix` (`RepPrefixKind`): Rep prefix or `RepPrefixKind.NONE` + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If `address_size` is not one of 16, 32, 64. + """ + ... + @staticmethod + def create_repe_scasw(address_size: int) -> Instruction: + """ + Creates a `REPE SCASW` instruction + + ### Args: + + - `address_size` (int): (`u32`) 16, 32, or 64 + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If `address_size` is not one of 16, 32, 64. + """ + ... + @staticmethod + def create_repne_scasw(address_size: int) -> Instruction: + """ + Creates a `REPNE SCASW` instruction + + ### Args: + + - `address_size` (int): (`u32`) 16, 32, or 64 + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If `address_size` is not one of 16, 32, 64. + """ + ... + @staticmethod + def create_scasd(address_size: int, rep_prefix: RepPrefixKind = RepPrefixKind.NONE) -> Instruction: + """ + Creates a `SCASD` instruction + + ### Args: + + - `address_size` (int): (`u32`) 16, 32, or 64 + - `rep_prefix` (`RepPrefixKind`): Rep prefix or `RepPrefixKind.NONE` + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If `address_size` is not one of 16, 32, 64. + """ + ... + @staticmethod + def create_repe_scasd(address_size: int) -> Instruction: + """ + Creates a `REPE SCASD` instruction + + ### Args: + + - `address_size` (int): (`u32`) 16, 32, or 64 + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If `address_size` is not one of 16, 32, 64. + """ + ... + @staticmethod + def create_repne_scasd(address_size: int) -> Instruction: + """ + Creates a `REPNE SCASD` instruction + + ### Args: + + - `address_size` (int): (`u32`) 16, 32, or 64 + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If `address_size` is not one of 16, 32, 64. + """ + ... + @staticmethod + def create_scasq(address_size: int, rep_prefix: RepPrefixKind = RepPrefixKind.NONE) -> Instruction: + """ + Creates a `SCASQ` instruction + + ### Args: + + - `address_size` (int): (`u32`) 16, 32, or 64 + - `rep_prefix` (`RepPrefixKind`): Rep prefix or `RepPrefixKind.NONE` + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If `address_size` is not one of 16, 32, 64. + """ + ... + @staticmethod + def create_repe_scasq(address_size: int) -> Instruction: + """ + Creates a `REPE SCASQ` instruction + + ### Args: + + - `address_size` (int): (`u32`) 16, 32, or 64 + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If `address_size` is not one of 16, 32, 64. + """ + ... + @staticmethod + def create_repne_scasq(address_size: int) -> Instruction: + """ + Creates a `REPNE SCASQ` instruction + + ### Args: + + - `address_size` (int): (`u32`) 16, 32, or 64 + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If `address_size` is not one of 16, 32, 64. + """ + ... + @staticmethod + def create_insb(address_size: int, rep_prefix: RepPrefixKind = RepPrefixKind.NONE) -> Instruction: + """ + Creates a `INSB` instruction + + ### Args: + + - `address_size` (int): (`u32`) 16, 32, or 64 + - `rep_prefix` (`RepPrefixKind`): Rep prefix or `RepPrefixKind.NONE` + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If `address_size` is not one of 16, 32, 64. + """ + ... + @staticmethod + def create_rep_insb(address_size: int) -> Instruction: + """ + Creates a `REP INSB` instruction + + ### Args: + + - `address_size` (int): (`u32`) 16, 32, or 64 + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If `address_size` is not one of 16, 32, 64. + """ + ... + @staticmethod + def create_insw(address_size: int, rep_prefix: RepPrefixKind = RepPrefixKind.NONE) -> Instruction: + """ + Creates a `INSW` instruction + + ### Args: + + - `address_size` (int): (`u32`) 16, 32, or 64 + - `rep_prefix` (`RepPrefixKind`): Rep prefix or `RepPrefixKind.NONE` + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If `address_size` is not one of 16, 32, 64. + """ + ... + @staticmethod + def create_rep_insw(address_size: int) -> Instruction: + """ + Creates a `REP INSW` instruction + + ### Args: + + - `address_size` (int): (`u32`) 16, 32, or 64 + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If `address_size` is not one of 16, 32, 64. + """ + ... + @staticmethod + def create_insd(address_size: int, rep_prefix: RepPrefixKind = RepPrefixKind.NONE) -> Instruction: + """ + Creates a `INSD` instruction + + ### Args: + + - `address_size` (int): (`u32`) 16, 32, or 64 + - `rep_prefix` (`RepPrefixKind`): Rep prefix or `RepPrefixKind.NONE` + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If `address_size` is not one of 16, 32, 64. + """ + ... + @staticmethod + def create_rep_insd(address_size: int) -> Instruction: + """ + Creates a `REP INSD` instruction + + ### Args: + + - `address_size` (int): (`u32`) 16, 32, or 64 + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If `address_size` is not one of 16, 32, 64. + """ + ... + @staticmethod + def create_stosb(address_size: int, rep_prefix: RepPrefixKind = RepPrefixKind.NONE) -> Instruction: + """ + Creates a `STOSB` instruction + + ### Args: + + - `address_size` (int): (`u32`) 16, 32, or 64 + - `rep_prefix` (`RepPrefixKind`): Rep prefix or `RepPrefixKind.NONE` + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If `address_size` is not one of 16, 32, 64. + """ + ... + @staticmethod + def create_rep_stosb(address_size: int) -> Instruction: + """ + Creates a `REP STOSB` instruction + + ### Args: + + - `address_size` (int): (`u32`) 16, 32, or 64 + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If `address_size` is not one of 16, 32, 64. + """ + ... + @staticmethod + def create_stosw(address_size: int, rep_prefix: RepPrefixKind = RepPrefixKind.NONE) -> Instruction: + """ + Creates a `STOSW` instruction + + ### Args: + + - `address_size` (int): (`u32`) 16, 32, or 64 + - `rep_prefix` (`RepPrefixKind`): Rep prefix or `RepPrefixKind.NONE` + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If `address_size` is not one of 16, 32, 64. + """ + ... + @staticmethod + def create_rep_stosw(address_size: int) -> Instruction: + """ + Creates a `REP STOSW` instruction + + ### Args: + + - `address_size` (int): (`u32`) 16, 32, or 64 + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If `address_size` is not one of 16, 32, 64. + """ + ... + @staticmethod + def create_stosd(address_size: int, rep_prefix: RepPrefixKind = RepPrefixKind.NONE) -> Instruction: + """ + Creates a `STOSD` instruction + + ### Args: + + - `address_size` (int): (`u32`) 16, 32, or 64 + - `rep_prefix` (`RepPrefixKind`): Rep prefix or `RepPrefixKind.NONE` + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If `address_size` is not one of 16, 32, 64. + """ + ... + @staticmethod + def create_rep_stosd(address_size: int) -> Instruction: + """ + Creates a `REP STOSD` instruction + + ### Args: + + - `address_size` (int): (`u32`) 16, 32, or 64 + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If `address_size` is not one of 16, 32, 64. + """ + ... + @staticmethod + def create_stosq(address_size: int, rep_prefix: RepPrefixKind = RepPrefixKind.NONE) -> Instruction: + """ + Creates a `STOSQ` instruction + + ### Args: + + - `address_size` (int): (`u32`) 16, 32, or 64 + - `rep_prefix` (`RepPrefixKind`): Rep prefix or `RepPrefixKind.NONE` + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If `address_size` is not one of 16, 32, 64. + """ + ... + @staticmethod + def create_rep_stosq(address_size: int) -> Instruction: + """ + Creates a `REP STOSQ` instruction + + ### Args: + + - `address_size` (int): (`u32`) 16, 32, or 64 + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If `address_size` is not one of 16, 32, 64. + """ + ... + @staticmethod + def create_cmpsb(address_size: int, segment_prefix: Register = Register.NONE, rep_prefix: RepPrefixKind = RepPrefixKind.NONE) -> Instruction: + """ + Creates a `CMPSB` instruction + + ### Args: + + - `address_size` (int): (`u32`) 16, 32, or 64 + - `segment_prefix` (`Register`): Segment override or `Register.NONE` + - `rep_prefix` (`RepPrefixKind`): Rep prefix or `RepPrefixKind.NONE` + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If `address_size` is not one of 16, 32, 64. + """ + ... + @staticmethod + def create_repe_cmpsb(address_size: int) -> Instruction: + """ + Creates a `REPE CMPSB` instruction + + ### Args: + + - `address_size` (int): (`u32`) 16, 32, or 64 + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If `address_size` is not one of 16, 32, 64. + """ + ... + @staticmethod + def create_repne_cmpsb(address_size: int) -> Instruction: + """ + Creates a `REPNE CMPSB` instruction + + ### Args: + + - `address_size` (int): (`u32`) 16, 32, or 64 + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If `address_size` is not one of 16, 32, 64. + """ + ... + @staticmethod + def create_cmpsw(address_size: int, segment_prefix: Register = Register.NONE, rep_prefix: RepPrefixKind = RepPrefixKind.NONE) -> Instruction: + """ + Creates a `CMPSW` instruction + + ### Args: + + - `address_size` (int): (`u32`) 16, 32, or 64 + - `segment_prefix` (`Register`): Segment override or `Register.NONE` + - `rep_prefix` (`RepPrefixKind`): Rep prefix or `RepPrefixKind.NONE` + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If `address_size` is not one of 16, 32, 64. + """ + ... + @staticmethod + def create_repe_cmpsw(address_size: int) -> Instruction: + """ + Creates a `REPE CMPSW` instruction + + ### Args: + + - `address_size` (int): (`u32`) 16, 32, or 64 + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If `address_size` is not one of 16, 32, 64. + """ + ... + @staticmethod + def create_repne_cmpsw(address_size: int) -> Instruction: + """ + Creates a `REPNE CMPSW` instruction + + ### Args: + + - `address_size` (int): (`u32`) 16, 32, or 64 + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If `address_size` is not one of 16, 32, 64. + """ + ... + @staticmethod + def create_cmpsd(address_size: int, segment_prefix: Register = Register.NONE, rep_prefix: RepPrefixKind = RepPrefixKind.NONE) -> Instruction: + """ + Creates a `CMPSD` instruction + + ### Args: + + - `address_size` (int): (`u32`) 16, 32, or 64 + - `segment_prefix` (`Register`): Segment override or `Register.NONE` + - `rep_prefix` (`RepPrefixKind`): Rep prefix or `RepPrefixKind.NONE` + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If `address_size` is not one of 16, 32, 64. + """ + ... + @staticmethod + def create_repe_cmpsd(address_size: int) -> Instruction: + """ + Creates a `REPE CMPSD` instruction + + ### Args: + + - `address_size` (int): (`u32`) 16, 32, or 64 + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If `address_size` is not one of 16, 32, 64. + """ + ... + @staticmethod + def create_repne_cmpsd(address_size: int) -> Instruction: + """ + Creates a `REPNE CMPSD` instruction + + ### Args: + + - `address_size` (int): (`u32`) 16, 32, or 64 + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If `address_size` is not one of 16, 32, 64. + """ + ... + @staticmethod + def create_cmpsq(address_size: int, segment_prefix: Register = Register.NONE, rep_prefix: RepPrefixKind = RepPrefixKind.NONE) -> Instruction: + """ + Creates a `CMPSQ` instruction + + ### Args: + + - `address_size` (int): (`u32`) 16, 32, or 64 + - `segment_prefix` (`Register`): Segment override or `Register.NONE` + - `rep_prefix` (`RepPrefixKind`): Rep prefix or `RepPrefixKind.NONE` + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If `address_size` is not one of 16, 32, 64. + """ + ... + @staticmethod + def create_repe_cmpsq(address_size: int) -> Instruction: + """ + Creates a `REPE CMPSQ` instruction + + ### Args: + + - `address_size` (int): (`u32`) 16, 32, or 64 + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If `address_size` is not one of 16, 32, 64. + """ + ... + @staticmethod + def create_repne_cmpsq(address_size: int) -> Instruction: + """ + Creates a `REPNE CMPSQ` instruction + + ### Args: + + - `address_size` (int): (`u32`) 16, 32, or 64 + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If `address_size` is not one of 16, 32, 64. + """ + ... + @staticmethod + def create_movsb(address_size: int, segment_prefix: Register = Register.NONE, rep_prefix: RepPrefixKind = RepPrefixKind.NONE) -> Instruction: + """ + Creates a `MOVSB` instruction + + ### Args: + + - `address_size` (int): (`u32`) 16, 32, or 64 + - `segment_prefix` (`Register`): Segment override or `Register.NONE` + - `rep_prefix` (`RepPrefixKind`): Rep prefix or `RepPrefixKind.NONE` + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If `address_size` is not one of 16, 32, 64. + """ + ... + @staticmethod + def create_rep_movsb(address_size: int) -> Instruction: + """ + Creates a `REP MOVSB` instruction + + ### Args: + + - `address_size` (int): (`u32`) 16, 32, or 64 + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If `address_size` is not one of 16, 32, 64. + """ + ... + @staticmethod + def create_movsw(address_size: int, segment_prefix: Register = Register.NONE, rep_prefix: RepPrefixKind = RepPrefixKind.NONE) -> Instruction: + """ + Creates a `MOVSW` instruction + + ### Args: + + - `address_size` (int): (`u32`) 16, 32, or 64 + - `segment_prefix` (`Register`): Segment override or `Register.NONE` + - `rep_prefix` (`RepPrefixKind`): Rep prefix or `RepPrefixKind.NONE` + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If `address_size` is not one of 16, 32, 64. + """ + ... + @staticmethod + def create_rep_movsw(address_size: int) -> Instruction: + """ + Creates a `REP MOVSW` instruction + + ### Args: + + - `address_size` (int): (`u32`) 16, 32, or 64 + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If `address_size` is not one of 16, 32, 64. + """ + ... + @staticmethod + def create_movsd(address_size: int, segment_prefix: Register = Register.NONE, rep_prefix: RepPrefixKind = RepPrefixKind.NONE) -> Instruction: + """ + Creates a `MOVSD` instruction + + ### Args: + + - `address_size` (int): (`u32`) 16, 32, or 64 + - `segment_prefix` (`Register`): Segment override or `Register.NONE` + - `rep_prefix` (`RepPrefixKind`): Rep prefix or `RepPrefixKind.NONE` + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If `address_size` is not one of 16, 32, 64. + """ + ... + @staticmethod + def create_rep_movsd(address_size: int) -> Instruction: + """ + Creates a `REP MOVSD` instruction + + ### Args: + + - `address_size` (int): (`u32`) 16, 32, or 64 + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If `address_size` is not one of 16, 32, 64. + """ + ... + @staticmethod + def create_movsq(address_size: int, segment_prefix: Register = Register.NONE, rep_prefix: RepPrefixKind = RepPrefixKind.NONE) -> Instruction: + """ + Creates a `MOVSQ` instruction + + ### Args: + + - `address_size` (int): (`u32`) 16, 32, or 64 + - `segment_prefix` (`Register`): Segment override or `Register.NONE` + - `rep_prefix` (`RepPrefixKind`): Rep prefix or `RepPrefixKind.NONE` + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If `address_size` is not one of 16, 32, 64. + """ + ... + @staticmethod + def create_rep_movsq(address_size: int) -> Instruction: + """ + Creates a `REP MOVSQ` instruction + + ### Args: + + - `address_size` (int): (`u32`) 16, 32, or 64 + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If `address_size` is not one of 16, 32, 64. + """ + ... + @staticmethod + def create_maskmovq(address_size: int, register1: Register, register2: Register, segment_prefix: Register = Register.NONE) -> Instruction: + """ + Creates a `MASKMOVQ` instruction + + ### Args: + + - `address_size` (int): (`u32`) 16, 32, or 64 + - `register1` (`Register`): Register + - `register2` (`Register`): Register + - `segment_prefix` (`Register`): Segment override or `Register.NONE` + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If `address_size` is not one of 16, 32, 64. + """ + ... + @staticmethod + def create_maskmovdqu(address_size: int, register1: Register, register2: Register, segment_prefix: Register = Register.NONE) -> Instruction: + """ + Creates a `MASKMOVDQU` instruction + + ### Args: + + - `address_size` (int): (`u32`) 16, 32, or 64 + - `register1` (`Register`): Register + - `register2` (`Register`): Register + - `segment_prefix` (`Register`): Segment override or `Register.NONE` + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If `address_size` is not one of 16, 32, 64. + """ + ... + @staticmethod + def create_vmaskmovdqu(address_size: int, register1: Register, register2: Register, segment_prefix: Register = Register.NONE) -> Instruction: + """ + Creates a `VMASKMOVDQU` instruction + + ### Args: + + - `address_size` (int): (`u32`) 16, 32, or 64 + - `register1` (`Register`): Register + - `register2` (`Register`): Register + - `segment_prefix` (`Register`): Segment override or `Register.NONE` + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If `address_size` is not one of 16, 32, 64. + """ + ... + @staticmethod + def create_declare_byte_1(b0: int) -> Instruction: + """ + Creates a `db`/`.byte` asm directive + + ### Args: + + - `b0` (int): (`u8`) Byte 0 + + ### Returns: + + - `Instruction`: Created instruction + """ + ... + @staticmethod + def create_declare_byte_2(b0: int, b1: int) -> Instruction: + """ + Creates a `db`/`.byte` asm directive + + ### Args: + + - `b0` (int): (`u8`) Byte 0 + - `b1` (int): (`u8`) Byte 1 + + ### Returns: + + - `Instruction`: Created instruction + """ + ... + @staticmethod + def create_declare_byte_3(b0: int, b1: int, b2: int) -> Instruction: + """ + Creates a `db`/`.byte` asm directive + + ### Args: + + - `b0` (int): (`u8`) Byte 0 + - `b1` (int): (`u8`) Byte 1 + - `b2` (int): (`u8`) Byte 2 + + ### Returns: + + - `Instruction`: Created instruction + """ + ... + @staticmethod + def create_declare_byte_4(b0: int, b1: int, b2: int, b3: int) -> Instruction: + """ + Creates a `db`/`.byte` asm directive + + ### Args: + + - `b0` (int): (`u8`) Byte 0 + - `b1` (int): (`u8`) Byte 1 + - `b2` (int): (`u8`) Byte 2 + - `b3` (int): (`u8`) Byte 3 + + ### Returns: + + - `Instruction`: Created instruction + """ + ... + @staticmethod + def create_declare_byte_5(b0: int, b1: int, b2: int, b3: int, b4: int) -> Instruction: + """ + Creates a `db`/`.byte` asm directive + + ### Args: + + - `b0` (int): (`u8`) Byte 0 + - `b1` (int): (`u8`) Byte 1 + - `b2` (int): (`u8`) Byte 2 + - `b3` (int): (`u8`) Byte 3 + - `b4` (int): (`u8`) Byte 4 + + ### Returns: + + - `Instruction`: Created instruction + """ + ... + @staticmethod + def create_declare_byte_6(b0: int, b1: int, b2: int, b3: int, b4: int, b5: int) -> Instruction: + """ + Creates a `db`/`.byte` asm directive + + ### Args: + + - `b0` (int): (`u8`) Byte 0 + - `b1` (int): (`u8`) Byte 1 + - `b2` (int): (`u8`) Byte 2 + - `b3` (int): (`u8`) Byte 3 + - `b4` (int): (`u8`) Byte 4 + - `b5` (int): (`u8`) Byte 5 + + ### Returns: + + - `Instruction`: Created instruction + """ + ... + @staticmethod + def create_declare_byte_7(b0: int, b1: int, b2: int, b3: int, b4: int, b5: int, b6: int) -> Instruction: + """ + Creates a `db`/`.byte` asm directive + + ### Args: + + - `b0` (int): (`u8`) Byte 0 + - `b1` (int): (`u8`) Byte 1 + - `b2` (int): (`u8`) Byte 2 + - `b3` (int): (`u8`) Byte 3 + - `b4` (int): (`u8`) Byte 4 + - `b5` (int): (`u8`) Byte 5 + - `b6` (int): (`u8`) Byte 6 + + ### Returns: + + - `Instruction`: Created instruction + """ + ... + @staticmethod + def create_declare_byte_8(b0: int, b1: int, b2: int, b3: int, b4: int, b5: int, b6: int, b7: int) -> Instruction: + """ + Creates a `db`/`.byte` asm directive + + ### Args: + + - `b0` (int): (`u8`) Byte 0 + - `b1` (int): (`u8`) Byte 1 + - `b2` (int): (`u8`) Byte 2 + - `b3` (int): (`u8`) Byte 3 + - `b4` (int): (`u8`) Byte 4 + - `b5` (int): (`u8`) Byte 5 + - `b6` (int): (`u8`) Byte 6 + - `b7` (int): (`u8`) Byte 7 + + ### Returns: + + - `Instruction`: Created instruction + """ + ... + @staticmethod + def create_declare_byte_9(b0: int, b1: int, b2: int, b3: int, b4: int, b5: int, b6: int, b7: int, b8: int) -> Instruction: + """ + Creates a `db`/`.byte` asm directive + + ### Args: + + - `b0` (int): (`u8`) Byte 0 + - `b1` (int): (`u8`) Byte 1 + - `b2` (int): (`u8`) Byte 2 + - `b3` (int): (`u8`) Byte 3 + - `b4` (int): (`u8`) Byte 4 + - `b5` (int): (`u8`) Byte 5 + - `b6` (int): (`u8`) Byte 6 + - `b7` (int): (`u8`) Byte 7 + - `b8` (int): (`u8`) Byte 8 + + ### Returns: + + - `Instruction`: Created instruction + """ + ... + @staticmethod + def create_declare_byte_10(b0: int, b1: int, b2: int, b3: int, b4: int, b5: int, b6: int, b7: int, b8: int, b9: int) -> Instruction: + """ + Creates a `db`/`.byte` asm directive + + ### Args: + + - `b0` (int): (`u8`) Byte 0 + - `b1` (int): (`u8`) Byte 1 + - `b2` (int): (`u8`) Byte 2 + - `b3` (int): (`u8`) Byte 3 + - `b4` (int): (`u8`) Byte 4 + - `b5` (int): (`u8`) Byte 5 + - `b6` (int): (`u8`) Byte 6 + - `b7` (int): (`u8`) Byte 7 + - `b8` (int): (`u8`) Byte 8 + - `b9` (int): (`u8`) Byte 9 + + ### Returns: + + - `Instruction`: Created instruction + """ + ... + @staticmethod + def create_declare_byte_11(b0: int, b1: int, b2: int, b3: int, b4: int, b5: int, b6: int, b7: int, b8: int, b9: int, b10: int) -> Instruction: + """ + Creates a `db`/`.byte` asm directive + + ### Args: + + - `b0` (int): (`u8`) Byte 0 + - `b1` (int): (`u8`) Byte 1 + - `b2` (int): (`u8`) Byte 2 + - `b3` (int): (`u8`) Byte 3 + - `b4` (int): (`u8`) Byte 4 + - `b5` (int): (`u8`) Byte 5 + - `b6` (int): (`u8`) Byte 6 + - `b7` (int): (`u8`) Byte 7 + - `b8` (int): (`u8`) Byte 8 + - `b9` (int): (`u8`) Byte 9 + - `b10` (int): (`u8`) Byte 10 + + ### Returns: + + - `Instruction`: Created instruction + """ + ... + @staticmethod + def create_declare_byte_12(b0: int, b1: int, b2: int, b3: int, b4: int, b5: int, b6: int, b7: int, b8: int, b9: int, b10: int, b11: int) -> Instruction: + """ + Creates a `db`/`.byte` asm directive + + ### Args: + + - `b0` (int): (`u8`) Byte 0 + - `b1` (int): (`u8`) Byte 1 + - `b2` (int): (`u8`) Byte 2 + - `b3` (int): (`u8`) Byte 3 + - `b4` (int): (`u8`) Byte 4 + - `b5` (int): (`u8`) Byte 5 + - `b6` (int): (`u8`) Byte 6 + - `b7` (int): (`u8`) Byte 7 + - `b8` (int): (`u8`) Byte 8 + - `b9` (int): (`u8`) Byte 9 + - `b10` (int): (`u8`) Byte 10 + - `b11` (int): (`u8`) Byte 11 + + ### Returns: + + - `Instruction`: Created instruction + """ + ... + @staticmethod + def create_declare_byte_13(b0: int, b1: int, b2: int, b3: int, b4: int, b5: int, b6: int, b7: int, b8: int, b9: int, b10: int, b11: int, b12: int) -> Instruction: + """ + Creates a `db`/`.byte` asm directive + + ### Args: + + - `b0` (int): (`u8`) Byte 0 + - `b1` (int): (`u8`) Byte 1 + - `b2` (int): (`u8`) Byte 2 + - `b3` (int): (`u8`) Byte 3 + - `b4` (int): (`u8`) Byte 4 + - `b5` (int): (`u8`) Byte 5 + - `b6` (int): (`u8`) Byte 6 + - `b7` (int): (`u8`) Byte 7 + - `b8` (int): (`u8`) Byte 8 + - `b9` (int): (`u8`) Byte 9 + - `b10` (int): (`u8`) Byte 10 + - `b11` (int): (`u8`) Byte 11 + - `b12` (int): (`u8`) Byte 12 + + ### Returns: + + - `Instruction`: Created instruction + """ + ... + @staticmethod + def create_declare_byte_14(b0: int, b1: int, b2: int, b3: int, b4: int, b5: int, b6: int, b7: int, b8: int, b9: int, b10: int, b11: int, b12: int, b13: int) -> Instruction: + """ + Creates a `db`/`.byte` asm directive + + ### Args: + + - `b0` (int): (`u8`) Byte 0 + - `b1` (int): (`u8`) Byte 1 + - `b2` (int): (`u8`) Byte 2 + - `b3` (int): (`u8`) Byte 3 + - `b4` (int): (`u8`) Byte 4 + - `b5` (int): (`u8`) Byte 5 + - `b6` (int): (`u8`) Byte 6 + - `b7` (int): (`u8`) Byte 7 + - `b8` (int): (`u8`) Byte 8 + - `b9` (int): (`u8`) Byte 9 + - `b10` (int): (`u8`) Byte 10 + - `b11` (int): (`u8`) Byte 11 + - `b12` (int): (`u8`) Byte 12 + - `b13` (int): (`u8`) Byte 13 + + ### Returns: + + - `Instruction`: Created instruction + """ + ... + @staticmethod + def create_declare_byte_15(b0: int, b1: int, b2: int, b3: int, b4: int, b5: int, b6: int, b7: int, b8: int, b9: int, b10: int, b11: int, b12: int, b13: int, b14: int) -> Instruction: + """ + Creates a `db`/`.byte` asm directive + + ### Args: + + - `b0` (int): (`u8`) Byte 0 + - `b1` (int): (`u8`) Byte 1 + - `b2` (int): (`u8`) Byte 2 + - `b3` (int): (`u8`) Byte 3 + - `b4` (int): (`u8`) Byte 4 + - `b5` (int): (`u8`) Byte 5 + - `b6` (int): (`u8`) Byte 6 + - `b7` (int): (`u8`) Byte 7 + - `b8` (int): (`u8`) Byte 8 + - `b9` (int): (`u8`) Byte 9 + - `b10` (int): (`u8`) Byte 10 + - `b11` (int): (`u8`) Byte 11 + - `b12` (int): (`u8`) Byte 12 + - `b13` (int): (`u8`) Byte 13 + - `b14` (int): (`u8`) Byte 14 + + ### Returns: + + - `Instruction`: Created instruction + """ + ... + @staticmethod + def create_declare_byte_16(b0: int, b1: int, b2: int, b3: int, b4: int, b5: int, b6: int, b7: int, b8: int, b9: int, b10: int, b11: int, b12: int, b13: int, b14: int, b15: int) -> Instruction: + """ + Creates a `db`/`.byte` asm directive + + ### Args: + + - `b0` (int): (`u8`) Byte 0 + - `b1` (int): (`u8`) Byte 1 + - `b2` (int): (`u8`) Byte 2 + - `b3` (int): (`u8`) Byte 3 + - `b4` (int): (`u8`) Byte 4 + - `b5` (int): (`u8`) Byte 5 + - `b6` (int): (`u8`) Byte 6 + - `b7` (int): (`u8`) Byte 7 + - `b8` (int): (`u8`) Byte 8 + - `b9` (int): (`u8`) Byte 9 + - `b10` (int): (`u8`) Byte 10 + - `b11` (int): (`u8`) Byte 11 + - `b12` (int): (`u8`) Byte 12 + - `b13` (int): (`u8`) Byte 13 + - `b14` (int): (`u8`) Byte 14 + - `b15` (int): (`u8`) Byte 15 + + ### Returns: + + - `Instruction`: Created instruction + """ + ... + @staticmethod + def create_declare_byte(data: Union[bytes, bytearray]) -> Instruction: + """ + Creates a `db`/`.byte` asm directive + + ### Args: + + - `data` (bytes, bytearray): Data + + ### Returns: + + - `Instruction`: Created instruction + + ### Raises: + + - ValueError: If `len(data)` is not 1-16 + - TypeError: If `data` is not a supported type + """ + ... + @staticmethod + def create_declare_word_1(w0: int) -> Instruction: + """ + Creates a `dw`/`.word` asm directive + + ### Args: + + - `w0` (int): (`u16`) Word 0 + + ### Returns: + + - `Instruction`: Created instruction + """ + ... + @staticmethod + def create_declare_word_2(w0: int, w1: int) -> Instruction: + """ + Creates a `dw`/`.word` asm directive + + ### Args: + + - `w0` (int): (`u16`) Word 0 + - `w1` (int): (`u16`) Word 1 + + ### Returns: + + - `Instruction`: Created instruction + """ + ... + @staticmethod + def create_declare_word_3(w0: int, w1: int, w2: int) -> Instruction: + """ + Creates a `dw`/`.word` asm directive + + ### Args: + + - `w0` (int): (`u16`) Word 0 + - `w1` (int): (`u16`) Word 1 + - `w2` (int): (`u16`) Word 2 + + ### Returns: + + - `Instruction`: Created instruction + """ + ... + @staticmethod + def create_declare_word_4(w0: int, w1: int, w2: int, w3: int) -> Instruction: + """ + Creates a `dw`/`.word` asm directive + + ### Args: + + - `w0` (int): (`u16`) Word 0 + - `w1` (int): (`u16`) Word 1 + - `w2` (int): (`u16`) Word 2 + - `w3` (int): (`u16`) Word 3 + + ### Returns: + + - `Instruction`: Created instruction + """ + ... + @staticmethod + def create_declare_word_5(w0: int, w1: int, w2: int, w3: int, w4: int) -> Instruction: + """ + Creates a `dw`/`.word` asm directive + + ### Args: + + - `w0` (int): (`u16`) Word 0 + - `w1` (int): (`u16`) Word 1 + - `w2` (int): (`u16`) Word 2 + - `w3` (int): (`u16`) Word 3 + - `w4` (int): (`u16`) Word 4 + + ### Returns: + + - `Instruction`: Created instruction + """ + ... + @staticmethod + def create_declare_word_6(w0: int, w1: int, w2: int, w3: int, w4: int, w5: int) -> Instruction: + """ + Creates a `dw`/`.word` asm directive + + ### Args: + + - `w0` (int): (`u16`) Word 0 + - `w1` (int): (`u16`) Word 1 + - `w2` (int): (`u16`) Word 2 + - `w3` (int): (`u16`) Word 3 + - `w4` (int): (`u16`) Word 4 + - `w5` (int): (`u16`) Word 5 + + ### Returns: + + - `Instruction`: Created instruction + """ + ... + @staticmethod + def create_declare_word_7(w0: int, w1: int, w2: int, w3: int, w4: int, w5: int, w6: int) -> Instruction: + """ + Creates a `dw`/`.word` asm directive + + ### Args: + + - `w0` (int): (`u16`) Word 0 + - `w1` (int): (`u16`) Word 1 + - `w2` (int): (`u16`) Word 2 + - `w3` (int): (`u16`) Word 3 + - `w4` (int): (`u16`) Word 4 + - `w5` (int): (`u16`) Word 5 + - `w6` (int): (`u16`) Word 6 + + ### Returns: + + - `Instruction`: Created instruction + """ + ... + @staticmethod + def create_declare_word_8(w0: int, w1: int, w2: int, w3: int, w4: int, w5: int, w6: int, w7: int) -> Instruction: + """ + Creates a `dw`/`.word` asm directive + + ### Args: + + - `w0` (int): (`u16`) Word 0 + - `w1` (int): (`u16`) Word 1 + - `w2` (int): (`u16`) Word 2 + - `w3` (int): (`u16`) Word 3 + - `w4` (int): (`u16`) Word 4 + - `w5` (int): (`u16`) Word 5 + - `w6` (int): (`u16`) Word 6 + - `w7` (int): (`u16`) Word 7 + + ### Returns: + + - `Instruction`: Created instruction + """ + ... + @staticmethod + def create_declare_dword_1(d0: int) -> Instruction: + """ + Creates a `dd`/`.int` asm directive + + ### Args: + + - `d0` (int): (`u32`) Dword 0 + + ### Returns: + + - `Instruction`: Created instruction + """ + ... + @staticmethod + def create_declare_dword_2(d0: int, d1: int) -> Instruction: + """ + Creates a `dd`/`.int` asm directive + + ### Args: + + - `d0` (int): (`u32`) Dword 0 + - `d1` (int): (`u32`) Dword 1 + + ### Returns: + + - `Instruction`: Created instruction + """ + ... + @staticmethod + def create_declare_dword_3(d0: int, d1: int, d2: int) -> Instruction: + """ + Creates a `dd`/`.int` asm directive + + ### Args: + + - `d0` (int): (`u32`) Dword 0 + - `d1` (int): (`u32`) Dword 1 + - `d2` (int): (`u32`) Dword 2 + + ### Returns: + + - `Instruction`: Created instruction + """ + ... + @staticmethod + def create_declare_dword_4(d0: int, d1: int, d2: int, d3: int) -> Instruction: + """ + Creates a `dd`/`.int` asm directive + + ### Args: + + - `d0` (int): (`u32`) Dword 0 + - `d1` (int): (`u32`) Dword 1 + - `d2` (int): (`u32`) Dword 2 + - `d3` (int): (`u32`) Dword 3 + + ### Returns: + + - `Instruction`: Created instruction + """ + ... + @staticmethod + def create_declare_qword_1(q0: int) -> Instruction: + """ + Creates a `dq`/`.quad` asm directive + + ### Args: + + - `q0` (int): (`u64`) Qword 0 + + ### Returns: + + - `Instruction`: Created instruction + """ + ... + @staticmethod + def create_declare_qword_2(q0: int, q1: int) -> Instruction: + """ + Creates a `dq`/`.quad` asm directive + + ### Args: + + - `q0` (int): (`u64`) Qword 0 + - `q1` (int): (`u64`) Qword 1 + + ### Returns: + + - `Instruction`: Created instruction + """ + ... class Decoder: + """ + Decodes 16/32/64-bit x86 instructions + + ### Args: + + - `bitness` (int): 16, 32 or 64 + - `data` (bytes, bytearray): Data to decode. For best PERF, use `bytes` since it's immutable and nothing gets copied. + - `options` (`DecoderOptions`): (default = `DecoderOptions.NONE`) Decoder options, eg. `DecoderOptions.NO_INVALID_CHECK` | `DecoderOptions.AMD` + + ### Raises: + + - ValueError: If `bitness` is invalid + - TypeError: If `data` is not a supported type + + ### Examples: + + ```python + from iced_x86 import * + + data = b"\\x86\\x64\\x32\\x16\\xF0\\xF2\\x83\\x00\\x5A\\x62\\xC1\\xFE\\xCB\\x6F\\xD3" + decoder = Decoder(64, data) + decoder.ip = 0x1234_5678 + + # The decoder is iterable + for instr in decoder: + print(f"Decoded: IP=0x{instr.ip:X}: {instr}") + ``` + + Output: + + ```text + Decoded: IP=0x12345678: xchg ah,[rdx+rsi+16h] + Decoded: IP=0x1234567C: xacquire lock add dword ptr [rax],5Ah + Decoded: IP=0x12345681: vmovdqu64 zmm18{k3}{z},zmm11 + ``` + + ```python + from iced_x86 import * + + # xchg ah,[rdx+rsi+16h] + # xacquire lock add dword ptr [rax],5Ah + # vmovdqu64 zmm18{k3}{z},zmm11 + data = b"\\x86\\x64\\x32\\x16\\xF0\\xF2\\x83\\x00\\x5A\\x62\\xC1\\xFE\\xCB\\x6F\\xD3" + decoder = Decoder(64, data) + decoder.ip = 0x1234_5678 + + instr1 = decoder.decode() + assert instr1.code == Code.XCHG_RM8_R8 + assert instr1.mnemonic == Mnemonic.XCHG + assert instr1.len == 4 + + instr2 = decoder.decode() + assert instr2.code == Code.ADD_RM32_IMM8 + assert instr2.mnemonic == Mnemonic.ADD + assert instr2.len == 5 + + instr3 = decoder.decode() + assert instr3.code == Code.EVEX_VMOVDQU64_ZMM_K1Z_ZMMM512 + assert instr3.mnemonic == Mnemonic.VMOVDQU64 + assert instr3.len == 6 + ``` + + It's sometimes useful to decode some invalid instructions, eg. `lock add esi,ecx`. + Pass in `DecoderOptions.NO_INVALID_CHECK` to the constructor and the decoder + will decode some invalid encodings. + + ```python + from iced_x86 import * + + # lock add esi,ecx # lock not allowed + data = b"\\xF0\\x01\\xCE" + decoder = Decoder(64, data) + decoder.ip = 0x1234_5678 + instr = decoder.decode() + assert instr.code == Code.INVALID + + # We want to decode some instructions with invalid encodings + decoder = Decoder(64, data, DecoderOptions.NO_INVALID_CHECK) + decoder.ip = 0x1234_5678 + instr = decoder.decode() + assert instr.code == Code.ADD_RM32_R32 + assert instr.has_lock_prefix + ``` + """ def __init__(self, bitness: int, data: Union[bytes, bytearray], options: DecoderOptions = DecoderOptions.NONE) -> None: ... @property - def ip(self) -> int: ... + def ip(self) -> int: + """ + int: (`u64`) The current `IP`/`EIP`/`RIP` value, see also `Decoder.position` + + ### Note: + + - The setter only updates the IP value, it does not change the data position, use the `Decoder.position` setter to change the position. + """ + ... @ip.setter def ip(self, new_value: int) -> None: ... @property - def bitness(self) -> int: ... + def bitness(self) -> int: + """int: Gets the bitness (16, 32 or 64)""" + ... @property - def max_position(self) -> int: ... + def max_position(self) -> int: + """ + int: (`usize`) Gets the max value that can be written to `Decoder.position`. + + This is the size of the data that gets decoded to instructions and it's the length of the data that was passed to the constructor. + """ + ... @property - def position(self) -> int: ... + def position(self) -> int: + """ + int: (`usize`) The current data position, which is the index into the data passed to the constructor. + + This value is always <= `Decoder.max_position`. When `Decoder.position` == `Decoder.max_position`, it's not possible to decode more + instructions and `Decoder.can_decode` returns `False`. + + ### Raises: + + - ValueError: If the new position is invalid. + + ### Examples: + + ```python + from iced_x86 import * + + # nop and pause + data = b"\\x90\\xF3\\x90" + decoder = Decoder(64, data) + decoder.ip = 0x1234_5678 + + assert decoder.position == 0 + assert decoder.max_position == 3 + instr = decoder.decode() + assert decoder.position == 1 + assert instr.code == Code.NOPD + + instr = decoder.decode() + assert decoder.position == 3 + assert instr.code == Code.PAUSE + + # Start all over again + decoder.position = 0 + decoder.ip = 0x1234_5678 + assert decoder.position == 0 + assert decoder.decode().code == Code.NOPD + assert decoder.decode().code == Code.PAUSE + assert decoder.position == 3 + ``` + """ + ... @position.setter def position(self, new_value: int) -> None: ... @property - def can_decode(self) -> bool: ... + def can_decode(self) -> bool: + """ + bool: Returns `True` if there's at least one more byte to decode. + + It doesn't verify that the next instruction is valid, it only checks if there's + at least one more byte to read. See also `Decoder.position` and `Decoder.max_position`. + + It's not required to call this method. If this method returns `False`, then `Decoder.decode_out` + and `Decoder.decode` will return an instruction whose `Instruction.code` == `Code.INVALID`. + + ### Examples: + + ```python + from iced_x86 import * + + # nop and an incomplete instruction + data = b"\\x90\\xF3\\x0F" + decoder = Decoder(64, data) + decoder.ip = 0x1234_5678 + + # 3 bytes left to read + assert decoder.can_decode + instr = decoder.decode() + assert instr.code == Code.NOPD + + # 2 bytes left to read + assert decoder.can_decode + instr = decoder.decode() + # Not enough bytes left to decode a full instruction + assert decoder.last_error == DecoderError.NO_MORE_BYTES + assert instr.code == Code.INVALID + assert not instr + assert instr.is_invalid + + # 0 bytes left to read + assert not decoder.can_decode + ``` + """ + ... @property - def last_error(self) -> DecoderError: ... - def decode(self) -> Instruction: ... - def decode_out(self, instruction: Instruction) -> None: ... - def get_constant_offsets(self, instruction: Instruction) -> ConstantOffsets: ... + def last_error(self) -> DecoderError: + """ + `DecoderError`: Gets the last decoder error (a `DecoderError` enum value). + + Unless you need to know the reason it failed, it's better to check `Instruction.is_invalid` or `if not instruction:`. + """ + ... + def decode(self) -> Instruction: + """ + Decodes and returns the next instruction. + + See also `Decoder.decode_out` which avoids copying the decoded instruction to the caller's return variable. + See also `Decoder.last_error`. + + ### Returns: + + - Instruction: The next instruction + + ### Examples: + + ```python + from iced_x86 import * + + # xrelease lock add [rax],ebx + data = b"\\xF0\\xF3\\x01\\x18" + decoder = Decoder(64, data) + decoder.ip = 0x1234_5678 + instr = decoder.decode() + + assert instr.code == Code.ADD_RM32_R32 + assert instr.mnemonic == Mnemonic.ADD + assert instr.len == 4 + assert instr.op_count == 2 + + assert instr.op0_kind == OpKind.MEMORY + assert instr.memory_base == Register.RAX + assert instr.memory_index == Register.NONE + assert instr.memory_index_scale == 1 + assert instr.memory_displacement == 0 + assert instr.memory_segment == Register.DS + assert instr.segment_prefix == Register.NONE + assert instr.memory_size == MemorySize.UINT32 + + assert instr.op1_kind == OpKind.REGISTER + assert instr.op1_register == Register.EBX + + assert instr.has_lock_prefix + assert instr.has_xrelease_prefix + ``` + """ + ... + def decode_out(self, instruction: Instruction) -> None: + """ + Decodes the next instruction. + + The difference between this method and `Decoder.decode` is that this method doesn't need to + allocate a new instruction since it overwrites the input instruction. + + See also `Decoder.last_error`. + + ### Args: + + - `instruction` (`Instruction`): Updated with the decoded instruction. + + ### Examples: + + ```python + from iced_x86 import * + + # xrelease lock add [rax],ebx + data = b"\\xF0\\xF3\\x01\\x18" + decoder = Decoder(64, data) + decoder.ip = 0x1234_5678 + instr = Instruction() + decoder.decode_out(instr) + + assert instr.code == Code.ADD_RM32_R32 + assert instr.mnemonic == Mnemonic.ADD + assert instr.len == 4 + assert instr.op_count == 2 + + assert instr.op0_kind == OpKind.MEMORY + assert instr.memory_base == Register.RAX + assert instr.memory_index == Register.NONE + assert instr.memory_index_scale == 1 + assert instr.memory_displacement == 0 + assert instr.memory_segment == Register.DS + assert instr.segment_prefix == Register.NONE + assert instr.memory_size == MemorySize.UINT32 + + assert instr.op1_kind == OpKind.REGISTER + assert instr.op1_register == Register.EBX + + assert instr.has_lock_prefix + assert instr.has_xrelease_prefix + ``` + """ + ... + def get_constant_offsets(self, instruction: Instruction) -> ConstantOffsets: + """ + Gets the offsets of the constants (memory displacement and immediate) in the decoded instruction. + + The caller can check if there are any relocations at those addresses. + + ### Args: + + - `instruction` (`Instruction`): The latest instruction that was decoded by this decoder + + ### Returns: + + - ConstantOffsets: Offsets and sizes of immediates + + ### Examples: + + ```python + from iced_x86 import * + + # nop + # xor dword ptr [rax-5AA5EDCCh],5Ah + # 00 01 02 03 04 05 06 + # \\opc\\mrm\\displacement___\\imm + data = b"\\x90\\x83\\xB3\\x34\\x12\\x5A\\xA5\\x5A" + decoder = Decoder(64, data) + decoder.ip = 0x1234_5678 + assert decoder.decode().code == Code.NOPD + instr = decoder.decode() + co = decoder.get_constant_offsets(instr) + + assert co.has_displacement + assert co.displacement_offset == 2 + assert co.displacement_size == 4 + assert co.has_immediate + assert co.immediate_offset == 6 + assert co.immediate_size == 1 + # It's not an instruction with two immediates (e.g. enter) + assert not co.has_immediate2 + assert co.immediate_offset2 == 0 + assert co.immediate_size2 == 0 + ``` + """ + ... def __iter__(self) -> Iterator[Instruction]: ... class Encoder: + """ + Encodes instructions decoded by the decoder or instructions created by other code. + + See also `BlockEncoder` which can encode any number of instructions. + + ### Args: + + - `bitness` (int): 16, 32 or 64 + - `capacity` (int): (default = 0) Initial capacity of the byte buffer + + ### Raises: + + - ValueError: If `bitness` is invalid + + ### Examples: + + ```python + from iced_x86 import * + + # xchg ah,[rdx+rsi+16h] + data = b"\\x86\\x64\\x32\\x16" + decoder = Decoder(64, data) + decoder.ip = 0x1234_5678 + instr = decoder.decode() + + encoder = Encoder(64) + try: + instr_len = encoder.encode(instr, 0x5555_5555) + assert instr_len == 4 + except ValueError as ex: + print(f"Failed to encode the instruction: {ex}") + raise + + # We're done, take ownership of the buffer + buffer = encoder.take_buffer() + assert buffer == b"\\x86\\x64\\x32\\x16" + ``` + """ def __init__(self, bitness: int, capacity: int = 0) -> None: ... - def encode(self, instruction: Instruction, rip: int) -> int: ... - def write_u8(self, value: int) -> None: ... - def take_buffer(self) -> bytes: ... - def get_constant_offsets(self) -> ConstantOffsets: ... + def encode(self, instruction: Instruction, rip: int) -> int: + """ + Encodes an instruction and returns the size of the encoded instruction + + ### Args: + + - `instruction` (Instruction): Instruction to encode + - `rip` (int): (`u64`) `RIP` of the encoded instruction + + ### Returns: + + - int: Size of the encoded instruction + + ### Raises: + + - ValueError: If it failed to encode the instruction (eg. a target branch / RIP-rel operand is too far away) + + ### Examples: + + ```python + from iced_x86 import * + + # je short $+4 + data = b"\\x75\\x02" + decoder = Decoder(64, data) + decoder.ip = 0x1234_5678 + instr = decoder.decode() + + encoder = Encoder(64) + try: + # Use a different IP (orig rip + 0x10) + instr_len = encoder.encode(instr, 0x1234_5688) + assert instr_len == 2 + except ValueError as ex: + print(f"Failed to encode the instruction: {ex}") + raise + + # We're done, take ownership of the buffer + buffer = encoder.take_buffer() + assert buffer == b"\\x75\\xF2" + ``` + """ + ... + def write_u8(self, value: int) -> None: + """ + Writes a byte to the output buffer + + ### Args: + + - `value` (int): (`u8`) Value to write + + ### Examples: + + ```python + from iced_x86 import * + + # je short $+4 + data = b"\\x75\\x02" + decoder = Decoder(64, data) + decoder.ip = 0x1234_5678 + instr = decoder.decode() + + encoder = Encoder(64) + # Add a random byte + encoder.write_u8(0x90) + + try: + # Use a different IP (orig rip + 0x10) + instr_len = encoder.encode(instr, 0x1234_5688) + assert instr_len == 2 + except ValueError as ex: + print(f"Failed to encode the instruction: {ex}") + raise + + # Add a random byte + encoder.write_u8(0x90) + + # We're done, take ownership of the buffer + buffer = encoder.take_buffer() + assert buffer == b"\\x90\\x75\\xF2\\x90" + ``` + """ + ... + def take_buffer(self) -> bytes: + """ + Returns the buffer and initializes the internal buffer to an empty array. + + Should be called when you've encoded all instructions and need the raw instruction bytes. + + ### Returns: + + - bytes: The encoded instructions + """ + ... + def get_constant_offsets(self) -> ConstantOffsets: + """ + Gets the offsets of the constants (memory displacement and immediate) in the encoded instruction. + + The caller can use this information to add relocations if needed. + + ### Returns: + + - ConstantOffsets: Offsets and sizes of immediates + """ + ... @property - def prevent_vex2(self) -> bool: ... + def prevent_vex2(self) -> bool: + """bool: Disables 2-byte VEX encoding and encodes all VEX instructions with the 3-byte VEX encoding""" + ... @prevent_vex2.setter def prevent_vex2(self, new_value: bool) -> None: ... @property - def vex_wig(self) -> int: ... + def vex_wig(self) -> int: + """int: (`u8`) Value of the `VEX.W` bit to use if it's an instruction that ignores the bit. Default is 0.""" + ... @vex_wig.setter def vex_wig(self, new_value: int) -> None: ... @property - def vex_lig(self) -> int: ... + def vex_lig(self) -> int: + """int: (`u8`) Value of the `VEX.L` bit to use if it's an instruction that ignores the bit. Default is 0.""" + ... @vex_lig.setter def vex_lig(self, new_value: int) -> None: ... @property - def evex_wig(self) -> int: ... + def evex_wig(self) -> int: + """int: (`u8`) Value of the `EVEX.W` bit to use if it's an instruction that ignores the bit. Default is 0.""" + ... @evex_wig.setter def evex_wig(self, new_value: int) -> None: ... @property - def evex_lig(self) -> int: ... + def evex_lig(self) -> int: + """int: (`u8`) Value of the `EVEX.L'L` bits to use if it's an instruction that ignores the bits. Default is 0.""" + ... @evex_lig.setter def evex_lig(self, new_value: int) -> None: ... @property - def bitness(self) -> int: ... + def bitness(self) -> int: + """int: Gets the bitness (16, 32 or 64)""" + ... class Formatter: + """ + x86 formatter that supports GNU Assembler, Intel XED, masm and nasm syntax + + ### Args: + + - `syntax` (`FormatterSyntax`): Formatter syntax + + ### Examples: + + ```python + from iced_x86 import * + + data = b"\\x62\\xF2\\x4F\\xDD\\x72\\x50\\x01" + decoder = Decoder(64, data) + instr = decoder.decode() + + formatter = Formatter(FormatterSyntax.MASM) + formatter.uppercase_mnemonics = True + disasm = formatter.format(instr) + assert disasm == "VCVTNE2PS2BF16 zmm2{k5}{z},zmm6,dword bcst [rax+4]" + ``` + """ def __init__(self, syntax: FormatterSyntax) -> None: ... - def format(self, instruction: Instruction) -> str: ... - def format_mnemonic(self, instruction: Instruction, options: FormatMnemonicOptions = FormatMnemonicOptions.NONE) -> str: ... - def operand_count(self, instruction: Instruction) -> int: ... - def op_access(self, instruction: Instruction, operand: int) -> Optional[OpAccess]: ... - def get_instruction_operand(self, instruction: Instruction, operand: int) -> Optional[int]: ... - def get_formatter_operand(self, instruction: Instruction, instruction_operand: int) -> Optional[int]: ... - def format_operand(self, instruction: Instruction, operand: int) -> str: ... - def format_operand_separator(self, instruction: Instruction) -> str: ... - def format_all_operands(self, instruction: Instruction) -> str: ... - def format_register(self, register: Register) -> str: ... - def format_i8(self, value: int) -> str: ... - def format_i16(self, value: int) -> str: ... - def format_i32(self, value: int) -> str: ... - def format_i64(self, value: int) -> str: ... - def format_u8(self, value: int) -> str: ... - def format_u16(self, value: int) -> str: ... - def format_u32(self, value: int) -> str: ... - def format_u64(self, value: int) -> str: ... + def format(self, instruction: Instruction) -> str: + """ + Formats the whole instruction: prefixes, mnemonic, operands + + ### Args: + + - `instruction` (Instruction): Instruction to format + + ### Returns: + + - str: The formatted string + """ + ... + def format_mnemonic(self, instruction: Instruction, options: FormatMnemonicOptions = FormatMnemonicOptions.NONE) -> str: + """ + Formats the mnemonic and any prefixes + + ### Args: + + - `instruction` (Instruction): Instruction to format + - `options` (`FormatMnemonicOptions`): (default = `FormatMnemonicOptions.NONE`) Options + + ### Returns: + + - str: The formatted string + """ + ... + def operand_count(self, instruction: Instruction) -> int: + """ + Gets the number of operands that will be formatted. A formatter can add and remove operands + + ### Args: + + - `instruction` (Instruction): Instruction + + ### Returns: + + - int: Operand count + """ + ... + def op_access(self, instruction: Instruction, operand: int) -> Optional[OpAccess]: + """ + Returns the operand access but only if it's an operand added by the formatter. + + If it's an operand that is part of `Instruction`, you should call eg. `InstructionInfoFactory.info`. + + ### Args: + + - `instruction` (Instruction): Instruction + - `operand` (int): Operand number, 0-based. This is a formatter operand and isn't necessarily the same as an instruction operand. See `Formatter.operand_count` + + ### Returns: + + - `OpAccess`, None: Operand access or `None` + + ### Raises: + + - ValueError: If `operand` is invalid + """ + ... + def get_instruction_operand(self, instruction: Instruction, operand: int) -> Optional[int]: + """ + Converts a formatter operand index to an instruction operand index. + + Returns `None` if it's an operand added by the formatter + + ### Args: + + - `instruction` (Instruction): Instruction + - `operand` (int): Operand number, 0-based. This is a formatter operand and isn't necessarily the same as an instruction operand. See `Formatter.operand_count` + + ### Returns: + + - int, None: Instruction operand or `None` if it's an operand added by the formatter + + ### Raises: + + - ValueError: If `operand` is invalid + """ + ... + def get_formatter_operand(self, instruction: Instruction, instruction_operand: int) -> Optional[int]: + """ + Converts an instruction operand index to a formatter operand index. + + Returns `None` if the instruction operand isn't used by the formatter + + ### Args: + + - `instruction` (Instruction): Instruction + - `instruction_operand` (int): Instruction operand + + ### Returns: + + - int, None: Instruction operand or `None` if the instruction operand isn't used by the formatter + + ### Raises: + + - ValueError: If `instruction_operand` is invalid + """ + ... + def format_operand(self, instruction: Instruction, operand: int) -> str: + """ + Formats an operand. + + ### Args: + + - `instruction` (Instruction): Instruction + - `operand` (int): Operand number, 0-based. This is a formatter operand and isn't necessarily the same as an instruction operand. See `Formatter.operand_count` + + ### Returns: + + - str: The formatted string + + ### Raises: + + - ValueError: If `operand` is invalid + """ + ... + def format_operand_separator(self, instruction: Instruction) -> str: + """ + Formats an operand separator + + ### Args: + + - `instruction` (Instruction): Instruction + + ### Returns: + + - str: The formatted string + """ + ... + def format_all_operands(self, instruction: Instruction) -> str: + """ + Formats all operands + + ### Args: + + - `instruction` (Instruction): Instruction to format + + ### Returns: + + - str: The formatted string + """ + ... + def format_register(self, register: Register) -> str: + """ + Formats a register + + ### Args: + + - `register` (`Register`): Register + + ### Returns: + + - str: The formatted string + """ + ... + def format_i8(self, value: int) -> str: + """ + Formats a `i8` + + ### Args: + + - `value` (int): (`i8`) Value + + ### Returns: + + - str: The formatted string + """ + ... + def format_i16(self, value: int) -> str: + """ + Formats a `i16` + + ### Args: + + - `value` (int): (`i16`) Value + + ### Returns: + + - str: The formatted string + """ + ... + def format_i32(self, value: int) -> str: + """ + Formats a `i32` + + ### Args: + + - `value` (int): (`i32`) Value + + ### Returns: + + - str: The formatted string + """ + ... + def format_i64(self, value: int) -> str: + """ + Formats a `i64` + + ### Args: + + - `value` (int): (`i64`) Value + + ### Returns: + + - str: The formatted string + """ + ... + def format_u8(self, value: int) -> str: + """ + Formats a `u8` + + ### Args: + + - `value` (int): (`u8`) Value + + ### Returns: + + - str: The formatted string + """ + ... + def format_u16(self, value: int) -> str: + """ + Formats a `u16` + + ### Args: + + - `value` (int): (`u16`) Value + + ### Returns: + + - str: The formatted string + """ + ... + def format_u32(self, value: int) -> str: + """ + Formats a `u32` + + ### Args: + + - `value` (int): (`u32`) Value + + ### Returns: + + - str: The formatted string + """ + ... + def format_u64(self, value: int) -> str: + """ + Formats a `u64` + + ### Args: + + - `value` (int): (`u64`) Value + + ### Returns: + + - str: The formatted string + """ + ... @property - def uppercase_prefixes(self) -> bool: ... + def uppercase_prefixes(self) -> bool: + """ + bool: Prefixes are upper cased + + ```text + Default Value Example + ------------------------- + `True` `REP stosd` + ✔️ `False` `rep stosd` + ``` + """ + ... @uppercase_prefixes.setter def uppercase_prefixes(self, new_value: bool) -> None: ... @property - def uppercase_mnemonics(self) -> bool: ... + def uppercase_mnemonics(self) -> bool: + """ + bool: Mnemonics are upper cased + + ```text + Default Value Example + ------------------------- + `True` `MOV rcx,rax` + ✔️ `False` `mov rcx,rax` + ``` + """ + ... @uppercase_mnemonics.setter def uppercase_mnemonics(self, new_value: bool) -> None: ... @property - def uppercase_registers(self) -> bool: ... + def uppercase_registers(self) -> bool: + """ + bool: Registers are upper cased + + ```text + Default Value Example + ------------------------- + `True` `mov RCX,[RAX+RDX*8]` + ✔️ `False` `mov rcx,[rax+rdx*8]` + ``` + """ + ... @uppercase_registers.setter def uppercase_registers(self, new_value: bool) -> None: ... @property - def uppercase_keywords(self) -> bool: ... + def uppercase_keywords(self) -> bool: + """ + bool: Keywords are upper cased (eg. `BYTE PTR`, `SHORT`) + + ```text + Default Value Example + ------------------------- + `True` `mov BYTE PTR [rcx],12h` + ✔️ `False` `mov byte ptr [rcx],12h` + ``` + """ + ... @uppercase_keywords.setter def uppercase_keywords(self, new_value: bool) -> None: ... @property - def uppercase_decorators(self) -> bool: ... + def uppercase_decorators(self) -> bool: + """ + bool: Upper case decorators, eg. `{z}`, `{sae}`, `{rd-sae}` (but not op mask registers: `{k1}`) + + ```text + Default Value Example + ------------------------- + `True` `vunpcklps xmm2{k5}{Z},xmm6,dword bcst [rax+4]` + ✔️ `False` `vunpcklps xmm2{k5}{z},xmm6,dword bcst [rax+4]` + ``` + """ + ... @uppercase_decorators.setter def uppercase_decorators(self, new_value: bool) -> None: ... @property - def uppercase_all(self) -> bool: ... + def uppercase_all(self) -> bool: + """ + bool: Everything is upper cased, except numbers and their prefixes/suffixes + + ```text + Default Value Example + ------------------------- + `True` `MOV EAX,GS:[RCX*4+0ffh]` + ✔️ `False` `mov eax,gs:[rcx*4+0ffh]` + ``` + """ + ... @uppercase_all.setter def uppercase_all(self, new_value: bool) -> None: ... @property - def first_operand_char_index(self) -> int: ... + def first_operand_char_index(self) -> int: + """ + int: (`u32`) Character index (0-based) where the first operand is formatted. Can be set to 0 to format it immediately after the mnemonic. + At least one space or tab is always added between the mnemonic and the first operand. + + ```text + Default Value Example + ----------------------- + ✔️ `0` `mov•rcx,rbp` + `8` `mov•••••rcx,rbp` + ``` + """ + ... @first_operand_char_index.setter def first_operand_char_index(self, new_value: int) -> None: ... @property - def tab_size(self) -> int: ... + def tab_size(self) -> int: + """ + int: (`u32`) Size of a tab character or 0 to use spaces + + Default: `0` + """ + ... @tab_size.setter def tab_size(self, new_value: int) -> None: ... @property - def space_after_operand_separator(self) -> bool: ... + def space_after_operand_separator(self) -> bool: + """ + bool: Add a space after the operand separator + + ```text + Default Value Example + ------------------------- + `True` `mov rax, rcx` + ✔️ `False` `mov rax,rcx` + ``` + """ + ... @space_after_operand_separator.setter def space_after_operand_separator(self, new_value: bool) -> None: ... @property - def space_after_memory_bracket(self) -> bool: ... + def space_after_memory_bracket(self) -> bool: + """ + bool: Add a space between the memory expression and the brackets + + ```text + Default Value Example + ------------------------- + `True` `mov eax,[ rcx+rdx ]` + ✔️ `False` `mov eax,[rcx+rdx]` + ``` + """ + ... @space_after_memory_bracket.setter def space_after_memory_bracket(self, new_value: bool) -> None: ... @property - def space_between_memory_add_operators(self) -> bool: ... + def space_between_memory_add_operators(self) -> bool: + """ + bool: Add spaces between memory operand `+` and `-` operators + + ```text + Default Value Example + ------------------------- + `True` `mov eax,[rcx + rdx*8 - 80h]` + ✔️ `False` `mov eax,[rcx+rdx*8-80h]` + ``` + """ + ... @space_between_memory_add_operators.setter def space_between_memory_add_operators(self, new_value: bool) -> None: ... @property - def space_between_memory_mul_operators(self) -> bool: ... + def space_between_memory_mul_operators(self) -> bool: + """ + bool: Add spaces between memory operand `*` operator + + ```text + Default Value Example + ------------------------- + `True` `mov eax,[rcx+rdx * 8-80h]` + ✔️ `False` `mov eax,[rcx+rdx*8-80h]` + ``` + """ + ... @space_between_memory_mul_operators.setter def space_between_memory_mul_operators(self, new_value: bool) -> None: ... @property - def scale_before_index(self) -> bool: ... + def scale_before_index(self) -> bool: + """ + bool: Show memory operand scale value before the index register + + ```text + Default Value Example + ------------------------- + `True` `mov eax,[8*rdx]` + ✔️ `False` `mov eax,[rdx*8]` + ``` + """ + ... @scale_before_index.setter def scale_before_index(self, new_value: bool) -> None: ... @property - def always_show_scale(self) -> bool: ... + def always_show_scale(self) -> bool: + """ + bool: Always show the scale value even if it's `*1` + + ```text + Default Value Example + ------------------------- + `True` `mov eax,[rbx+rcx*1]` + ✔️ `False` `mov eax,[rbx+rcx]` + ``` + """ + ... @always_show_scale.setter def always_show_scale(self, new_value: bool) -> None: ... @property - def always_show_segment_register(self) -> bool: ... + def always_show_segment_register(self) -> bool: + """ + bool: Always show the effective segment register. + + If the option is `False`, only show the segment register if there's a segment override prefix. + + ```text + Default Value Example + ------------------------- + `True` `mov eax,ds:[ecx]` + ✔️ `False` `mov eax,[ecx]` + ``` + """ + ... @always_show_segment_register.setter def always_show_segment_register(self, new_value: bool) -> None: ... @property - def show_zero_displacements(self) -> bool: ... + def show_zero_displacements(self) -> bool: + """ + bool: Show zero displacements + + ```text + Default Value Example + ------------------------- + `True` `mov eax,[rcx*2+0]` + ✔️ `False` `mov eax,[rcx*2]` + ``` + """ + ... @show_zero_displacements.setter def show_zero_displacements(self, new_value: bool) -> None: ... @property - def hex_prefix(self) -> str: ... + def hex_prefix(self) -> str: + """ + str: Hex number prefix or an empty string, eg. `"0x"` + + Default: `""` (masm/nasm/intel), `"0x"` (gas) + """ + ... @hex_prefix.setter def hex_prefix(self, new_value: str) -> None: ... @property - def hex_suffix(self) -> str: ... + def hex_suffix(self) -> str: + """ + str: Hex number suffix or an empty string, eg. `"h"` + + Default: `"h"` (masm/nasm/intel), `""` (gas) + """ + ... @hex_suffix.setter def hex_suffix(self, new_value: str) -> None: ... @property - def hex_digit_group_size(self) -> int: ... + def hex_digit_group_size(self) -> int: + """ + int: (`u8`) Size of a digit group, see also `Formatter.digit_separator` + + ```text + Default Value Example + ----------------------- + `0` `0x12345678` + ✔️ `4` `0x1234_5678` + ``` + """ + ... @hex_digit_group_size.setter def hex_digit_group_size(self, new_value: int) -> None: ... @property - def decimal_prefix(self) -> str: ... + def decimal_prefix(self) -> str: + """ + str: Decimal number prefix or an empty string + + Default: `""` + """ + ... @decimal_prefix.setter def decimal_prefix(self, new_value: str) -> None: ... @property - def decimal_suffix(self) -> str: ... + def decimal_suffix(self) -> str: + """ + str: Decimal number suffix or an empty string + + Default: `""` + """ + ... @decimal_suffix.setter def decimal_suffix(self, new_value: str) -> None: ... @property - def decimal_digit_group_size(self) -> int: ... + def decimal_digit_group_size(self) -> int: + """ + int: (`u8`) Size of a digit group, see also `Formatter.digit_separator` + + ```text + Default Value Example + ----------------------- + `0` `12345678` + ✔️ `3` `12_345_678` + ``` + """ + ... @decimal_digit_group_size.setter def decimal_digit_group_size(self, new_value: int) -> None: ... @property - def octal_prefix(self) -> str: ... + def octal_prefix(self) -> str: + """ + str: Octal number prefix or an empty string + + Default: `""` (masm/nasm/intel), `"0"` (gas) + """ + ... @octal_prefix.setter def octal_prefix(self, new_value: str) -> None: ... @property - def octal_suffix(self) -> str: ... + def octal_suffix(self) -> str: + """ + str: Octal number suffix or an empty string + + Default: `"o"` (masm/nasm/intel), `""` (gas) + """ + ... @octal_suffix.setter def octal_suffix(self, new_value: str) -> None: ... @property - def octal_digit_group_size(self) -> int: ... + def octal_digit_group_size(self) -> int: + """ + int: (`u8`) Size of a digit group, see also `Formatter.digit_separator` + + ```text + Default Value Example + ----------------------- + `0` `12345670` + ✔️ `4` `1234_5670` + ``` + """ + ... @octal_digit_group_size.setter def octal_digit_group_size(self, new_value: int) -> None: ... @property - def binary_prefix(self) -> str: ... + def binary_prefix(self) -> str: + """ + str: Binary number prefix or an empty string + + Default: `""` (masm/nasm/intel), `"0b"` (gas) + """ + ... @binary_prefix.setter def binary_prefix(self, new_value: str) -> None: ... @property - def binary_suffix(self) -> str: ... + def binary_suffix(self) -> str: + """ + str: Binary number suffix or an empty string + + Default: `"b"` (masm/nasm/intel), `""` (gas) + """ + ... @binary_suffix.setter def binary_suffix(self, new_value: str) -> None: ... @property - def binary_digit_group_size(self) -> int: ... + def binary_digit_group_size(self) -> int: + """ + int: (`u8`) Size of a digit group, see also `Formatter.digit_separator` + + ```text + Default Value Example + ----------------------- + `0` `11010111` + ✔️ `4` `1101_0111` + ``` + """ + ... @binary_digit_group_size.setter def binary_digit_group_size(self, new_value: int) -> None: ... @property - def digit_separator(self) -> str: ... + def digit_separator(self) -> str: + """ + str: Digit separator or an empty string. See also eg. `Formatter.hex_digit_group_size` + + ```text + Default Value Example + ----------------------- + ✔️ `""` `0x12345678` + `"_"` `0x1234_5678` + ``` + """ + ... @digit_separator.setter def digit_separator(self, new_value: str) -> None: ... @property - def leading_zeroes(self) -> bool: ... + def leading_zeroes(self) -> bool: + """ + bool: Add leading zeroes to hexadecimal/octal/binary numbers. + + This option has no effect on branch targets and displacements, use `Formatter.branch_leading_zeroes` + and `Formatter.displacement_leading_zeroes`. + + ```text + Default Value Example + ------------------------- + `True` `0x0000000A`/`0000000Ah` + ✔️ `False` `0xA`/`0Ah` + ``` + """ + ... @leading_zeroes.setter def leading_zeroes(self, new_value: bool) -> None: ... @property - def uppercase_hex(self) -> bool: ... + def uppercase_hex(self) -> bool: + """ + bool: Use upper case hex digits + + ```text + Default Value Example + ------------------------- + ✔️ `True` `0xFF` + `False` `0xff` + ``` + """ + ... @uppercase_hex.setter def uppercase_hex(self, new_value: bool) -> None: ... @property - def small_hex_numbers_in_decimal(self) -> bool: ... + def small_hex_numbers_in_decimal(self) -> bool: + """ + bool: Small hex numbers (-9 .. 9) are shown in decimal + + ```text + Default Value Example + ------------------------- + ✔️ `True` `9` + `False` `0x9` + ``` + """ + ... @small_hex_numbers_in_decimal.setter def small_hex_numbers_in_decimal(self, new_value: bool) -> None: ... @property - def add_leading_zero_to_hex_numbers(self) -> bool: ... + def add_leading_zero_to_hex_numbers(self) -> bool: + """ + bool: Add a leading zero to hex numbers if there's no prefix and the number starts with hex digits `A-F` + + ```text + Default Value Example + ------------------------- + ✔️ `True` `0FFh` + `False` `FFh` + ``` + """ + ... @add_leading_zero_to_hex_numbers.setter def add_leading_zero_to_hex_numbers(self, new_value: bool) -> None: ... @property - def number_base(self) -> int: ... + def number_base(self) -> int: + """ + int: Number base (`2`, `8`, `10`, `16`) + + ### Raises: + + - ValueError: If it's an invalid number base + + Default: `16` + """ + ... @number_base.setter def number_base(self, new_value: int) -> None: ... @property - def branch_leading_zeroes(self) -> bool: ... + def branch_leading_zeroes(self) -> bool: + """ + bool: Add leading zeroes to branch offsets. Used by `CALL NEAR`, `CALL FAR`, `JMP NEAR`, `JMP FAR`, `Jcc`, `LOOP`, `LOOPcc`, `XBEGIN` + + ```text + Default Value Example + ------------------------- + ✔️ `True` `je 00000123h` + `False` `je 123h` + ``` + """ + ... @branch_leading_zeroes.setter def branch_leading_zeroes(self, new_value: bool) -> None: ... @property - def signed_immediate_operands(self) -> bool: ... + def signed_immediate_operands(self) -> bool: + """ + bool: Show immediate operands as signed numbers + + ```text + Default Value Example + ------------------------- + `True` `mov eax,-1` + ✔️ `False` `mov eax,FFFFFFFF` + ``` + """ + ... @signed_immediate_operands.setter def signed_immediate_operands(self, new_value: bool) -> None: ... @property - def signed_memory_displacements(self) -> bool: ... + def signed_memory_displacements(self) -> bool: + """ + bool: Displacements are signed numbers + + ```text + Default Value Example + ------------------------- + ✔️ `True` `mov al,[eax-2000h]` + `False` `mov al,[eax+0FFFFE000h]` + ``` + """ + ... @signed_memory_displacements.setter def signed_memory_displacements(self, new_value: bool) -> None: ... @property - def displacement_leading_zeroes(self) -> bool: ... + def displacement_leading_zeroes(self) -> bool: + """ + bool: Add leading zeroes to displacements + + ```text + Default Value Example + ------------------------- + `True` `mov al,[eax+00000012h]` + ✔️ `False` `mov al,[eax+12h]` + ``` + """ + ... @displacement_leading_zeroes.setter def displacement_leading_zeroes(self, new_value: bool) -> None: ... @property - def memory_size_options(self) -> MemorySizeOptions: ... + def memory_size_options(self) -> MemorySizeOptions: + """ + `MemorySizeOptions`: Options that control if the memory size (eg. `DWORD PTR`) is shown or not. + + This is ignored by the gas (AT&T) formatter. + + Default: `MemorySizeOptions.DEFAULT` + """ + ... @memory_size_options.setter def memory_size_options(self, new_value: MemorySizeOptions) -> None: ... @property - def rip_relative_addresses(self) -> bool: ... + def rip_relative_addresses(self) -> bool: + """ + bool: Show `RIP+displ` or the virtual address + + ```text + Default Value Example + ------------------------- + `True` `mov eax,[rip+12345678h]` + ✔️ `False` `mov eax,[1029384756AFBECDh]` + ``` + """ + ... @rip_relative_addresses.setter def rip_relative_addresses(self, new_value: bool) -> None: ... @property - def show_branch_size(self) -> bool: ... + def show_branch_size(self) -> bool: + """ + bool: Show `NEAR`, `SHORT`, etc if it's a branch instruction + + ```text + Default Value Example + ------------------------- + ✔️ `True` `je short 1234h` + `False` `je 1234h` + ``` + """ + ... @show_branch_size.setter def show_branch_size(self, new_value: bool) -> None: ... @property - def use_pseudo_ops(self) -> bool: ... + def use_pseudo_ops(self) -> bool: + """ + bool: Use pseudo instructions + + ```text + Default Value Example + ------------------------- + ✔️ `True` `vcmpnltsd xmm2,xmm6,xmm3` + `False` `vcmpsd xmm2,xmm6,xmm3,5` + ``` + """ + ... @use_pseudo_ops.setter def use_pseudo_ops(self, new_value: bool) -> None: ... @property - def show_symbol_address(self) -> bool: ... + def show_symbol_address(self) -> bool: + """ + bool: Show the original value after the symbol name + + ```text + Default Value Example + ------------------------- + `True` `mov eax,[myfield (12345678)]` + ✔️ `False` `mov eax,[myfield]` + ``` + """ + ... @show_symbol_address.setter def show_symbol_address(self, new_value: bool) -> None: ... @property - def gas_naked_registers(self) -> bool: ... + def gas_naked_registers(self) -> bool: + """ + bool: (gas only): If `True`, the formatter doesn't add `%` to registers + + ```text + Default Value Example + ------------------------- + `True` `mov eax,ecx` + ✔️ `False` `mov %eax,%ecx` + ``` + """ + ... @gas_naked_registers.setter def gas_naked_registers(self, new_value: bool) -> None: ... @property - def gas_show_mnemonic_size_suffix(self) -> bool: ... + def gas_show_mnemonic_size_suffix(self) -> bool: + """ + bool: (gas only): Shows the mnemonic size suffix even when not needed + + ```text + Default Value Example + ------------------------- + `True` `movl %eax,%ecx` + ✔️ `False` `mov %eax,%ecx` + ``` + """ + ... @gas_show_mnemonic_size_suffix.setter def gas_show_mnemonic_size_suffix(self, new_value: bool) -> None: ... @property - def gas_space_after_memory_operand_comma(self) -> bool: ... + def gas_space_after_memory_operand_comma(self) -> bool: + """ + bool: (gas only): Add a space after the comma if it's a memory operand + + ```text + Default Value Example + ------------------------- + `True` `(%eax, %ecx, 2)` + ✔️ `False` `(%eax,%ecx,2)` + ``` + """ + ... @gas_space_after_memory_operand_comma.setter def gas_space_after_memory_operand_comma(self, new_value: bool) -> None: ... @property - def masm_add_ds_prefix32(self) -> bool: ... + def masm_add_ds_prefix32(self) -> bool: + """ + bool: (masm only): Add a `DS` segment override even if it's not present. Used if it's 16/32-bit code and mem op is a displ + + ```text + Default Value Example + ------------------------- + ✔️ `True` `mov eax,ds:[12345678]` + `False` `mov eax,[12345678]` + ``` + """ + ... @masm_add_ds_prefix32.setter def masm_add_ds_prefix32(self, new_value: bool) -> None: ... @property - def masm_symbol_displ_in_brackets(self) -> bool: ... + def masm_symbol_displ_in_brackets(self) -> bool: + """ + bool: (masm only): Show symbols in brackets + + ```text + Default Value Example + ------------------------- + ✔️ `True` `[ecx+symbol]` / `[symbol]` + `False` `symbol[ecx]` / `symbol` + ``` + """ + ... @masm_symbol_displ_in_brackets.setter def masm_symbol_displ_in_brackets(self, new_value: bool) -> None: ... @property - def masm_displ_in_brackets(self) -> bool: ... + def masm_displ_in_brackets(self) -> bool: + """ + bool: (masm only): Show displacements in brackets + + ```text + Default Value Example + ------------------------- + ✔️ `True` `[ecx+1234h]` + `False` `1234h[ecx]` + ``` + """ + ... @masm_displ_in_brackets.setter def masm_displ_in_brackets(self, new_value: bool) -> None: ... @property - def nasm_show_sign_extended_immediate_size(self) -> bool: ... + def nasm_show_sign_extended_immediate_size(self) -> bool: + """ + bool: (nasm only): Shows `BYTE`, `WORD`, `DWORD` or `QWORD` if it's a sign extended immediate operand value + + ```text + Default Value Example + ------------------------- + `True` `or rcx,byte -1` + ✔️ `False` `or rcx,-1` + ``` + """ + ... @nasm_show_sign_extended_immediate_size.setter def nasm_show_sign_extended_immediate_size(self, new_value: bool) -> None: ... @property - def prefer_st0(self) -> bool: ... + def prefer_st0(self) -> bool: + """ + bool: Use `st(0)` instead of `st` if `st` can be used. Ignored by the nasm formatter. + + ```text + Default Value Example + ------------------------- + `True` `fadd st(0),st(3)` + ✔️ `False` `fadd st,st(3)` + ``` + """ + ... @prefer_st0.setter def prefer_st0(self, new_value: bool) -> None: ... @property - def show_useless_prefixes(self) -> bool: ... + def show_useless_prefixes(self) -> bool: + """ + bool: Show useless prefixes. If it has useless prefixes, it could be data and not code. + + ```text + Default Value Example + ------------------------- + `True` `es rep add eax,ecx` + ✔️ `False` `add eax,ecx` + ``` + """ + ... @show_useless_prefixes.setter def show_useless_prefixes(self, new_value: bool) -> None: ... @property - def cc_b(self) -> CC_b: ... + def cc_b(self) -> CC_b: + """ + `CC_b`: Mnemonic condition code selector (eg. `JB` / `JC` / `JNAE`) + + Default: `JB`, `CMOVB`, `SETB` + """ + ... @cc_b.setter def cc_b(self, new_value: CC_b) -> None: ... @property - def cc_ae(self) -> CC_ae: ... + def cc_ae(self) -> CC_ae: + """ + `CC_ae`: Mnemonic condition code selector (eg. `JAE` / `JNB` / `JNC`) + + Default: `JAE`, `CMOVAE`, `SETAE` + """ + ... @cc_ae.setter def cc_ae(self, new_value: CC_ae) -> None: ... @property - def cc_e(self) -> CC_e: ... + def cc_e(self) -> CC_e: + """ + `CC_e`: Mnemonic condition code selector (eg. `JE` / `JZ`) + + Default: `JE`, `CMOVE`, `SETE`, `LOOPE`, `REPE` + """ + ... @cc_e.setter def cc_e(self, new_value: CC_e) -> None: ... @property - def cc_ne(self) -> CC_ne: ... + def cc_ne(self) -> CC_ne: + """ + `CC_ne`: Mnemonic condition code selector (eg. `JNE` / `JNZ`) + + Default: `JNE`, `CMOVNE`, `SETNE`, `LOOPNE`, `REPNE` + """ + ... @cc_ne.setter def cc_ne(self, new_value: CC_ne) -> None: ... @property - def cc_be(self) -> CC_be: ... + def cc_be(self) -> CC_be: + """ + `CC_be`: Mnemonic condition code selector (eg. `JBE` / `JNA`) + + Default: `JBE`, `CMOVBE`, `SETBE` + """ + ... @cc_be.setter def cc_be(self, new_value: CC_be) -> None: ... @property - def cc_a(self) -> CC_a: ... + def cc_a(self) -> CC_a: + """ + `CC_a`: Mnemonic condition code selector (eg. `JA` / `JNBE`) + + Default: `JA`, `CMOVA`, `SETA` + """ + ... @cc_a.setter def cc_a(self, new_value: CC_a) -> None: ... @property - def cc_p(self) -> CC_p: ... + def cc_p(self) -> CC_p: + """ + `CC_p`: Mnemonic condition code selector (eg. `JP` / `JPE`) + + Default: `JP`, `CMOVP`, `SETP` + """ + ... @cc_p.setter def cc_p(self, new_value: CC_p) -> None: ... @property - def cc_np(self) -> CC_np: ... + def cc_np(self) -> CC_np: + """ + `CC_np`: Mnemonic condition code selector (eg. `JNP` / `JPO`) + + Default: `JNP`, `CMOVNP`, `SETNP` + """ + ... @cc_np.setter def cc_np(self, new_value: CC_np) -> None: ... @property - def cc_l(self) -> CC_l: ... + def cc_l(self) -> CC_l: + """ + `CC_l`: Mnemonic condition code selector (eg. `JL` / `JNGE`) + + Default: `JL`, `CMOVL`, `SETL` + """ + ... @cc_l.setter def cc_l(self, new_value: CC_l) -> None: ... @property - def cc_ge(self) -> CC_ge: ... + def cc_ge(self) -> CC_ge: + """ + `CC_ge`: Mnemonic condition code selector (eg. `JGE` / `JNL`) + + Default: `JGE`, `CMOVGE`, `SETGE` + """ + ... @cc_ge.setter def cc_ge(self, new_value: CC_ge) -> None: ... @property - def cc_le(self) -> CC_le: ... + def cc_le(self) -> CC_le: + """ + `CC_le`: Mnemonic condition code selector (eg. `JLE` / `JNG`) + + Default: `JLE`, `CMOVLE`, `SETLE` + """ + ... @cc_le.setter def cc_le(self, new_value: CC_le) -> None: ... @property - def cc_g(self) -> CC_g: ... + def cc_g(self) -> CC_g: + """ + `CC_g`: Mnemonic condition code selector (eg. `JG` / `JNLE`) + + Default: `JG`, `CMOVG`, `SETG` + """ + ... @cc_g.setter def cc_g(self, new_value: CC_g) -> None: ... class FastFormatter: + """ + Fast formatter with less formatting options and with a masm-like syntax. + + Use it if formatting speed is more important than being able to re-assemble formatted instructions. + + This formatter is ~1.25x faster than the other formatters (the time includes decoding + formatting). + + ### Examples: + + ```python + from iced_x86 import * + + data = b"\\x62\\xF2\\x4F\\xDD\\x72\\x50\\x01" + decoder = Decoder(64, data) + instr = decoder.decode() + + formatter = FastFormatter() + formatter.space_after_operand_separator = True + disasm = formatter.format(instr) + assert disasm == "vcvtne2ps2bf16 zmm2{k5}{z}, zmm6, dword bcst [rax+4h]" + ``` + """ def __init__(self) -> None: ... - def format(self, instruction: Instruction) -> str: ... + def format(self, instruction: Instruction) -> str: + """ + Formats the whole instruction: prefixes, mnemonic, operands + + ### Args: + + - `instruction` (Instruction): Instruction to format + + ### Returns: + + - str: The formatted string + """ + ... @property - def space_after_operand_separator(self) -> bool: ... + def space_after_operand_separator(self) -> bool: + """ + bool: Add a space after the operand separator + + ```text + Default Value Example + ------------------------- + `True` `mov rax, rcx` + ✔️ `False` `mov rax,rcx` + ``` + """ + ... @space_after_operand_separator.setter def space_after_operand_separator(self, new_value: bool) -> None: ... @property - def rip_relative_addresses(self) -> bool: ... + def rip_relative_addresses(self) -> bool: + """ + bool: Show `RIP+displ` or the virtual address + + ```text + Default Value Example + ------------------------- + `True` `mov eax,[rip+12345678h]` + ✔️ `False` `mov eax,[1029384756AFBECDh]` + ``` + """ + ... @rip_relative_addresses.setter def rip_relative_addresses(self, new_value: bool) -> None: ... @property - def use_pseudo_ops(self) -> bool: ... + def use_pseudo_ops(self) -> bool: + """ + bool: Use pseudo instructions + + ```text + Default Value Example + ------------------------- + ✔️ `True` `vcmpnltsd xmm2,xmm6,xmm3` + `False` `vcmpsd xmm2,xmm6,xmm3,5` + ``` + """ + ... @use_pseudo_ops.setter def use_pseudo_ops(self, new_value: bool) -> None: ... @property - def show_symbol_address(self) -> bool: ... + def show_symbol_address(self) -> bool: + """ + bool: Show the original value after the symbol name + + ```text + Default Value Example + ------------------------- + `True` `mov eax,[myfield (12345678)]` + ✔️ `False` `mov eax,[myfield]` + ``` + """ + ... @show_symbol_address.setter def show_symbol_address(self, new_value: bool) -> None: ... @property - def always_show_segment_register(self) -> bool: ... + def always_show_segment_register(self) -> bool: + """ + bool: Always show the effective segment register. + + If the option is `False`, only show the segment register if there's a segment override prefix. + + ```text + Default Value Example + ------------------------- + `True` `mov eax,ds:[ecx]` + ✔️ `False` `mov eax,[ecx]` + ``` + """ + ... @always_show_segment_register.setter def always_show_segment_register(self, new_value: bool) -> None: ... @property - def always_show_memory_size(self) -> bool: ... + def always_show_memory_size(self) -> bool: + """ + bool: Always show the size of memory operands + + ```text + Default Value Example Example + ---------------------------------------------------- + `True` `mov eax,dword ptr [ebx]` `add byte ptr [eax],0x12` + ✔️ `False` `mov eax,[ebx]` `add byte ptr [eax],0x12` + ``` + """ + ... @always_show_memory_size.setter def always_show_memory_size(self, new_value: bool) -> None: ... @property - def uppercase_hex(self) -> bool: ... + def uppercase_hex(self) -> bool: + """ + bool: Use upper case hex digits + + ```text + Default Value Example + ------------------------- + ✔️ `True` `0xFF` + `False` `0xff` + ``` + """ + ... @uppercase_hex.setter def uppercase_hex(self, new_value: bool) -> None: ... @property - def use_hex_prefix(self) -> bool: ... + def use_hex_prefix(self) -> bool: + """ + bool: Use a hex prefix (`0x`) or a hex suffix (`h`) + + ```text + Default Value Example + ------------------------- + `True` `0x5A` + ✔️ `False` `5Ah` + ``` + """ + ... @use_hex_prefix.setter def use_hex_prefix(self, new_value: bool) -> None: ... class BlockEncoder: + """ + Encodes instructions + + `Encoder` can only encode one instruction at a time. This class can encode any number of + instructions and can also fix short branches if the target is too far away. + + It will fail if there's an instruction with a RIP-relative operand (`[rip+123h]`) and the target is too far away. + A workaround is to use a new base RIP of the encoded instructions that is close (+/-2GB) to the original location. + + ### Args: + + - `bitness` (int): 16, 32 or 64 + - `fix_branches` (bool): (default = `True`) Fix branches (eg. convert short to near branches if the target is too far away) + + ### Raises: + + - ValueError: If `bitness` is invalid + + ### Examples: + + ```python + from iced_x86 import * + + data = b"\\x86\\x64\\x32\\x16\\xF0\\xF2\\x83\\x00\\x5A\\x62\\xC1\\xFE\\xCB\\x6F\\xD3" + decoder = Decoder(64, data) + decoder.ip = 0x1234_5678 + + instrs = [instr for instr in decoder] + + encoder = BlockEncoder(64) + # Add an instruction + encoder.add(instrs[0]) + # Add more instructions + encoder.add_many(instrs[1:]) + try: + # Encode all added instructions and get the raw bytes + raw_data = encoder.encode(0x3456_789A) + except ValueError as ex: + print("Could not encode all instructions") + raise + + # It has no IP-relative instructions (eg. branches or [rip+xxx] ops) + # so the result should be identical to the original code. + assert data == raw_data + ``` + """ def __init__(self, bitness: int, fix_branches: bool = True) -> None: ... - def add(self, instruction: Instruction) -> None: ... - def add_many(self, instructions: List[Instruction]) -> None: ... - def encode(self, rip: int) -> bytes: ... + def add(self, instruction: Instruction) -> None: + """ + Adds an instruction that will be encoded when `BlockEncoder.encode` is called. + + The input `instruction` can be a decoded instruction or an instruction + created by the user, eg. `Instruction.create*()` methods. + + ### Args: + + - `instruction` (Instruction): Next instruction to encode + """ + ... + def add_many(self, instructions: List[Instruction]) -> None: + """ + Adds instructions that will be encoded when `BlockEncoder.encode` is called. + + ### Args: + + - `instructions` (List[Instruction]): Next instructions to encode + """ + ... + def encode(self, rip: int) -> bytes: + """ + Encodes all instructions added by `BlockEncoder.add`/`BlockEncoder.add_many` and returns the raw bytes + + ### Args: + + - `rip` (int): (`u64`) Base IP of all encoded instructions + + ### Returns: + + - bytes: All encoded instructions + + ### Raises: + + - ValueError: If one or more instructions couldn't be encoded + """ + ... class UsedRegister: + """A register used by an instruction""" @property - def register(self) -> Register: ... + def register(self) -> Register: + """`Register`: Gets the register""" + ... @property - def access(self) -> OpAccess: ... - def __copy__(self) -> UsedRegister: ... - def __deepcopy__(self, memo: Any) -> UsedRegister: ... - def clone(self) -> UsedRegister: ... + def access(self) -> OpAccess: + """`OpAccess`: Gets the register access""" + ... + def __copy__(self) -> UsedRegister: + """ + Returns a copy of this instance. + + ### Returns: + + - UsedRegister: A copy of this instance + + This is identical to `UsedRegister.clone` + """ + ... + def __deepcopy__(self, memo: Any) -> UsedRegister: + """ + Returns a copy of this instance. + + ### Args: + + - `memo` (Any): memo dict + + ### Returns: + + - UsedRegister: A copy of this instance + + This is identical to `UsedRegister.clone` + """ + ... + def clone(self) -> UsedRegister: + """ + Returns a copy of this instance. + + ### Returns: + + - UsedRegister: A copy of this instance + """ + ... def __eq__(self, other: Any) -> bool: ... def __ne__(self, other: Any) -> bool: ... def __hash__(self) -> int: ... class UsedMemory: + """A memory location used by an instruction""" @property - def segment(self) -> Register: ... + def segment(self) -> Register: + """`Register`: Effective segment register or `Register.NONE` if the segment register is ignored""" + ... @property - def base(self) -> Register: ... + def base(self) -> Register: + """`Register`: Base register or `Register.NONE` if none""" + ... @property - def index(self) -> Register: ... + def index(self) -> Register: + """`Register`: Index register or `Register.NONE` if none""" + ... @property - def scale(self) -> int: ... + def scale(self) -> int: + """int: Index scale (1, 2, 4 or 8)""" + ... @property - def displacement(self) -> int: ... + def displacement(self) -> int: + """int: (`u64`) Displacement""" + ... @property - def displacement_i64(self) -> int: ... + def displacement_i64(self) -> int: + """int: (`i64`) Displacement""" + ... @property - def memory_size(self) -> MemorySize: ... + def memory_size(self) -> MemorySize: + """`MemorySize`: Size of location (enum value)""" + ... @property - def access(self) -> OpAccess: ... + def access(self) -> OpAccess: + """`OpAccess`: Memory access""" + ... @property - def address_size(self) -> CodeSize: ... + def address_size(self) -> CodeSize: + """`CodeSize`: Address size""" + ... @property - def vsib_size(self) -> int: ... - def __copy__(self) -> UsedMemory: ... - def __deepcopy__(self, memo: Any) -> UsedMemory: ... - def clone(self) -> UsedMemory: ... + def vsib_size(self) -> int: + """int: VSIB size (`0`, `4` or `8`)""" + ... + def __copy__(self) -> UsedMemory: + """ + Returns a copy of this instance. + + ### Returns: + + - UsedMemory: A copy of this instance + + This is identical to `UsedMemory.clone` + """ + ... + def __deepcopy__(self, memo: Any) -> UsedMemory: + """ + Returns a copy of this instance. + + ### Args: + + - `memo` (Any): memo dict + + ### Returns: + + - UsedMemory: A copy of this instance + + This is identical to `UsedMemory.clone` + """ + ... + def clone(self) -> UsedMemory: + """ + Returns a copy of this instance. + + ### Returns: + + - UsedMemory: A copy of this instance + """ + ... def __eq__(self, other: Any) -> bool: ... def __ne__(self, other: Any) -> bool: ... def __hash__(self) -> int: ... class InstructionInfo: - def used_registers(self) -> List[UsedRegister]: ... - def used_memory(self) -> List[UsedMemory]: ... + """Contains accessed registers and memory locations""" + def used_registers(self) -> List[UsedRegister]: + """ + Gets all accessed registers. + + This method doesn't return all accessed registers if `Instruction.is_save_restore_instruction` is `True`. + + ### Returns: + + - List[UsedRegister]: All accessed registers + + Some instructions have a `r16`/`r32` operand but only use the low 8 bits of the register. In that case + this method returns the 8-bit register even if it's `SPL`, `BPL`, `SIL`, `DIL` and the + instruction was decoded in 16 or 32-bit mode. This is more accurate than returning the `r16`/`r32` + register. Example instructions that do this: `PINSRB`, `ARPL` + """ + ... + def used_memory(self) -> List[UsedMemory]: + """ + Gets all accessed memory locations + + ### Returns: + + - List[UsedMemory]: All accessed memory locations + """ + ... @property - def op0_access(self) -> OpAccess: ... + def op0_access(self) -> OpAccess: + """`OpAccess`: Operand #0 access""" + ... @property - def op1_access(self) -> OpAccess: ... + def op1_access(self) -> OpAccess: + """`OpAccess`: Operand #1 access""" + ... @property - def op2_access(self) -> OpAccess: ... + def op2_access(self) -> OpAccess: + """`OpAccess`: Operand #2 access""" + ... @property - def op3_access(self) -> OpAccess: ... + def op3_access(self) -> OpAccess: + """`OpAccess`: Operand #3 access""" + ... @property - def op4_access(self) -> OpAccess: ... - def op_access(self, operand: int) -> OpAccess: ... + def op4_access(self) -> OpAccess: + """`OpAccess`: Operand #4 access""" + ... + def op_access(self, operand: int) -> OpAccess: + """ + Gets operand access + + ### Args: + + - `operand` (int): Operand number, 0-4 + + ### Returns: + + - `OpAccess`: Operand access + + ### Raises: + + - ValueError: If `operand` is invalid + """ + ... class InstructionInfoFactory: + """ + Returns used registers and memory locations + + ### Examples: + + ```python + from iced_x86 import * + + # add [rdi+r12*8-5AA5EDCCh],esi + data = b"\\x42\\x01\\xB4\\xE7\\x34\\x12\\x5A\\xA5" + decoder = Decoder(64, data) + + def create_enum_dict(module): + return {module.__dict__[key]:key for key in module.__dict__ if isinstance(module.__dict__[key], int)} + + reg_to_str = create_enum_dict(Register) + op_access_to_str = create_enum_dict(OpAccess) + memsz_to_str = create_enum_dict(MemorySize) + + info_factory = InstructionInfoFactory() + for instr in decoder: + print(f"Instruction: {instr}") + + info = info_factory.info(instr) + + for mem_info in info.used_memory(): + # Register and OpAccess enum values + print(f"Used memory:") + print(f" seg: {reg_to_str[mem_info.segment]}") + print(f" base: {reg_to_str[mem_info.base]}") + print(f" index: {reg_to_str[mem_info.index]}") + print(f" scale: {mem_info.scale}") + print(f" displacement: 0x{mem_info.displacement:X}") + print(f" MemorySize enum: {memsz_to_str[mem_info.memory_size]}") + print(f" OpAccess enum: {op_access_to_str[mem_info.access]}") + + for reg_info in info.used_registers(): + print(f"Used register: reg={reg_to_str[reg_info.register]} access={op_access_to_str[reg_info.access]}") + ``` + + Output: + + ```text + Instruction: add [rdi+r12*8-5AA5EDCCh],esi + Used memory: + seg: DS + base: RDI + index: R12 + scale: 8 + displacement: 0xFFFFFFFFA55A1234 + MemorySize enum: UINT32 + OpAccess enum: READ_WRITE + Used register: reg=RDI access=READ + Used register: reg=R12 access=READ + Used register: reg=ESI access=READ + ``` + """ def __init__(self) -> None: ... - def info(self, instruction: Instruction) -> InstructionInfo: ... + def info(self, instruction: Instruction) -> InstructionInfo: + """ + Gets all accessed registers and memory locations + + ### Args: + + - `instruction` (Instruction): The instruction that should be analyzed + + ### Returns: + + - InstructionInfo: Accessed registers and memory locations + + ### Examples: + + ```python + from iced_x86 import * + + # add [rdi+r12*8-5AA5EDCCh],esi + data = b"\\x42\\x01\\xB4\\xE7\\x34\\x12\\x5A\\xA5" + decoder = Decoder(64, data) + info_factory = InstructionInfoFactory() + + instr = decoder.decode() + info = info_factory.info(instr) + + mem_list = info.used_memory() + assert len(mem_list) == 1 + mem = mem_list[0] + assert mem.segment == Register.DS + assert mem.base == Register.RDI + assert mem.index == Register.R12 + assert mem.scale == 8 + assert mem.displacement == 0xFFFFFFFFA55A1234 + assert mem.memory_size == MemorySize.UINT32 + assert mem.access == OpAccess.READ_WRITE + + regs = info.used_registers() + assert len(regs) == 3 + assert regs[0].register == Register.RDI + assert regs[0].access == OpAccess.READ + assert regs[1].register == Register.R12 + assert regs[1].access == OpAccess.READ + assert regs[2].register == Register.ESI + assert regs[2].access == OpAccess.READ + ``` + """ + ... class MemorySizeInfo: + """ + `MemorySize` enum info, see also `MemorySizeExt` + + ### Args: + + - `memory_size` (`MemorySize`): Enum value + + ### Examples: + + ```python + from iced_x86 import * + + info = MemorySizeInfo(MemorySize.PACKED256_UINT16); + assert info.size == 32 + ``` + """ def __init__(self, memory_size: MemorySize) -> None: ... @property - def memory_size(self) -> MemorySize: ... + def memory_size(self) -> MemorySize: + """ + `MemorySize`: Gets the `MemorySize` value + + ### Examples: + + ```python + from iced_x86 import * + + info = MemorySizeInfo(MemorySize.PACKED256_UINT16); + assert info.memory_size == MemorySize.PACKED256_UINT16 + ``` + """ + ... @property - def size(self) -> int: ... + def size(self) -> int: + """ + int: (`u32`) Gets the size in bytes of the memory location or 0 if it's not accessed or unknown + + ### Examples: + + ```python + from iced_x86 import * + + info = MemorySizeInfo(MemorySize.UINT32); + assert info.size == 4 + info = MemorySizeInfo(MemorySize.PACKED256_UINT16); + assert info.size == 32 + info = MemorySizeInfo(MemorySize.BROADCAST512_UINT64); + assert info.size == 8 + ``` + """ + ... @property - def element_size(self) -> int: ... + def element_size(self) -> int: + """ + int: (`u32`) Gets the size in bytes of the packed element. If it's not a packed data type, it's equal to `MemorySizeInfo.size`. + + ### Examples: + + ```python + from iced_x86 import * + + info = MemorySizeInfo(MemorySize.UINT32); + assert info.element_size == 4 + info = MemorySizeInfo(MemorySize.PACKED256_UINT16); + assert info.element_size == 2 + info = MemorySizeInfo(MemorySize.BROADCAST512_UINT64); + assert info.element_size == 8 + ``` + """ + ... @property - def element_type(self) -> MemorySize: ... + def element_type(self) -> MemorySize: + """ + `MemorySize`: Gets the element type if it's packed data or the type itself if it's not packed data + + ### Examples: + + ```python + from iced_x86 import * + + info = MemorySizeInfo(MemorySize.UINT32); + assert info.element_type == MemorySize.UINT32 + info = MemorySizeInfo(MemorySize.PACKED256_UINT16); + assert info.element_type == MemorySize.UINT16 + info = MemorySizeInfo(MemorySize.BROADCAST512_UINT64); + assert info.element_type == MemorySize.UINT64 + ``` + """ + ... @property - def element_type_info(self) -> MemorySizeInfo: ... + def element_type_info(self) -> MemorySizeInfo: + """ + `MemorySizeInfo`: Gets the element type if it's packed data or the type itself if it's not packed data + + ### Examples: + + ```python + from iced_x86 import * + + info = MemorySizeInfo(MemorySize.UINT32).element_type_info; + assert info.memory_size == MemorySize.UINT32 + info = MemorySizeInfo(MemorySize.PACKED256_UINT16).element_type_info; + assert info.memory_size == MemorySize.UINT16 + info = MemorySizeInfo(MemorySize.BROADCAST512_UINT64).element_type_info; + assert info.memory_size == MemorySize.UINT64 + ``` + """ + ... @property - def is_signed(self) -> bool: ... + def is_signed(self) -> bool: + """ + bool: `True` if it's signed data (signed integer or a floating point value) + + ### Examples: + + ```python + from iced_x86 import * + + info = MemorySizeInfo(MemorySize.UINT32); + assert not info.is_signed + info = MemorySizeInfo(MemorySize.INT32); + assert info.is_signed + info = MemorySizeInfo(MemorySize.FLOAT64); + assert info.is_signed + ``` + """ + ... @property - def is_broadcast(self) -> bool: ... + def is_broadcast(self) -> bool: + """ + bool: `True` if it's a broadcast memory type + + ### Examples: + + ```python + from iced_x86 import * + + info = MemorySizeInfo(MemorySize.UINT32); + assert not info.is_broadcast + info = MemorySizeInfo(MemorySize.PACKED256_UINT16); + assert not info.is_broadcast + info = MemorySizeInfo(MemorySize.BROADCAST512_UINT64); + assert info.is_broadcast + ``` + """ + ... @property - def is_packed(self) -> bool: ... + def is_packed(self) -> bool: + """ + bool: `True` if this is a packed data type, eg. `MemorySize.PACKED128_FLOAT32`. See also `MemorySizeInfo.element_count` + + ### Examples: + + ```python + from iced_x86 import * + + info = MemorySizeInfo(MemorySize.UINT32); + assert not info.is_packed + info = MemorySizeInfo(MemorySize.PACKED256_UINT16); + assert info.is_packed + info = MemorySizeInfo(MemorySize.BROADCAST512_UINT64); + assert not info.is_packed + ``` + """ + ... @property - def element_count(self) -> int: ... + def element_count(self) -> int: + """ + int: (`u32`) Gets the number of elements in the packed data type or `1` if it's not packed data (`MemorySizeInfo.is_packed`) + + ### Examples: + + ```python + from iced_x86 import * + + info = MemorySizeInfo(MemorySize.UINT32); + assert info.element_count == 1 + info = MemorySizeInfo(MemorySize.PACKED256_UINT16); + assert info.element_count == 16 + info = MemorySizeInfo(MemorySize.BROADCAST512_UINT64); + assert info.element_count == 1 + ``` + """ + ... class MemorySizeExt: + """`MemorySize` enum extension methods, see also `MemorySizeInfo`""" @staticmethod - def info(memory_size: MemorySize) -> MemorySizeInfo: ... + def info(memory_size: MemorySize) -> MemorySizeInfo: + """ + Gets the memory size info + + ### Args: + + - `memory_size` (`MemorySize`): Enum value + + ### Returns: + + - `MemorySizeInfo`: Memory size info + + ### Examples: + + ```python + from iced_x86 import * + + info = MemorySizeExt.info(MemorySize.PACKED256_UINT16); + assert info.size == 32 + ``` + """ + ... @staticmethod - def size(memory_size: MemorySize) -> int: ... + def size(memory_size: MemorySize) -> int: + """ + Gets the size in bytes of the memory location or 0 if it's not accessed by the instruction or unknown or variable sized + + ### Args: + + - `memory_size` (`MemorySize`): Enum value + + ### Returns: + + - int: (`u32`) Size in bytes of the memory location or + + ### Examples: + + ```python + from iced_x86 import * + + assert MemorySizeExt.size(MemorySize.UINT32) == 4 + assert MemorySizeExt.size(MemorySize.PACKED256_UINT16) == 32 + assert MemorySizeExt.size(MemorySize.BROADCAST512_UINT64) == 8 + ``` + """ + ... @staticmethod - def element_size(memory_size: MemorySize) -> int: ... + def element_size(memory_size: MemorySize) -> int: + """ + Gets the size in bytes of the packed element. If it's not a packed data type, it's equal to `MemorySizeExt.size`. + + ### Args: + + - `memory_size` (`MemorySize`): Enum value + + ### Returns: + + - int: (`u32`) Size in bytes of the packed element + + ### Examples: + + ```python + from iced_x86 import * + + assert MemorySizeExt.element_size(MemorySize.UINT32) == 4 + assert MemorySizeExt.element_size(MemorySize.PACKED256_UINT16) == 2 + assert MemorySizeExt.element_size(MemorySize.BROADCAST512_UINT64) == 8 + ``` + """ + ... @staticmethod - def element_type(memory_size: MemorySize) -> MemorySize: ... + def element_type(memory_size: MemorySize) -> MemorySize: + """ + Gets the element type if it's packed data or the input value if it's not packed data + + ### Args: + + - `memory_size` (`MemorySize`): Enum value + + ### Returns: + + - `MemorySize`: Element type + + ### Examples: + + ```python + from iced_x86 import * + + assert MemorySizeExt.element_type(MemorySize.UINT32) == MemorySize.UINT32 + assert MemorySizeExt.element_type(MemorySize.PACKED256_UINT16) == MemorySize.UINT16 + assert MemorySizeExt.element_type(MemorySize.BROADCAST512_UINT64) == MemorySize.UINT64 + ``` + """ + ... @staticmethod - def element_type_info(memory_size: MemorySize) -> MemorySizeInfo: ... + def element_type_info(memory_size: MemorySize) -> MemorySizeInfo: + """ + Gets the element type info if it's packed data or the input value if it's not packed data + + ### Args: + + - `memory_size` (`MemorySize`): Enum value + + ### Returns: + + - `MemorySizeInfo`: Element type info + + ### Examples: + + ```python + from iced_x86 import * + + assert MemorySizeExt.element_type_info(MemorySize.UINT32).memory_size == MemorySize.UINT32 + assert MemorySizeExt.element_type_info(MemorySize.PACKED256_UINT16).memory_size == MemorySize.UINT16 + assert MemorySizeExt.element_type_info(MemorySize.BROADCAST512_UINT64).memory_size == MemorySize.UINT64 + ``` + """ + ... @staticmethod - def is_signed(memory_size: MemorySize) -> bool: ... + def is_signed(memory_size: MemorySize) -> bool: + """ + `True` if it's signed data (signed integer or a floating point value) + + ### Args: + + - `memory_size` (`MemorySize`): Enum value + + ### Returns: + + - bool: `True` if it's signed data + + ### Examples: + + ```python + from iced_x86 import * + + assert not MemorySizeExt.is_signed(MemorySize.UINT32) + assert MemorySizeExt.is_signed(MemorySize.INT32) + assert MemorySizeExt.is_signed(MemorySize.FLOAT64) + ``` + """ + ... @staticmethod - def is_packed(memory_size: MemorySize) -> bool: ... + def is_packed(memory_size: MemorySize) -> bool: + """ + `True` if this is a packed data type, eg. `MemorySize.PACKED128_FLOAT32` + + ### Args: + + - `memory_size` (`MemorySize`): Enum value + + ### Returns: + + - bool: `True` if this is a packed data type + + ### Examples: + + ```python + from iced_x86 import * + + assert not MemorySizeExt.is_packed(MemorySize.UINT32) + assert MemorySizeExt.is_packed(MemorySize.PACKED256_UINT16) + assert not MemorySizeExt.is_packed(MemorySize.BROADCAST512_UINT64) + ``` + """ + ... @staticmethod - def element_count(memory_size: MemorySize) -> int: ... + def element_count(memory_size: MemorySize) -> int: + """ + Gets the number of elements in the packed data type or `1` if it's not packed data (`MemorySizeExt.is_packed`) + + ### Args: + + - `memory_size` (`MemorySize`): Enum value + + ### Returns: + + - int: (`u32`) Number of elements in the packed data type + + ### Examples: + + ```python + from iced_x86 import * + + assert MemorySizeExt.element_count(MemorySize.UINT32) == 1 + assert MemorySizeExt.element_count(MemorySize.PACKED256_UINT16) == 16 + assert MemorySizeExt.element_count(MemorySize.BROADCAST512_UINT64) == 1 + ``` + """ + ... @staticmethod - def is_broadcast(memory_size: MemorySize) -> bool: ... + def is_broadcast(memory_size: MemorySize) -> bool: + """ + `True` if it is a broadcast memory type + + ### Args: + + - `memory_size` (`MemorySize`): Enum value + + ### Returns: + + - bool: `True` if it is a broadcast memory type + + ### Examples: + + ```python + from iced_x86 import * + + assert not MemorySizeExt.is_broadcast(MemorySize.PACKED64_FLOAT16) + assert MemorySizeExt.is_broadcast(MemorySize.BROADCAST512_UINT64) + ``` + """ + ... class RegisterInfo: + """ + `Register` enum info, see also `RegisterExt` + + ### Args: + + - `register` (`Register`): Enum value + + ### Examples: + + ```python + from iced_x86 import * + + info = RegisterInfo(Register.GS) + assert info.number == 5 + ``` + """ def __init__(self, register: Register) -> None: ... @property - def register(self) -> Register: ... + def register(self) -> Register: + """ + `Register`: Gets the register value passed into the constructor + + ### Examples: + + ```python + from iced_x86 import * + + info = RegisterInfo(Register.EAX) + assert info.register == Register.EAX + ``` + """ + ... @property - def base(self) -> Register: ... + def base(self) -> Register: + """ + `Register`: Gets the base register, eg. `AL`, `AX`, `EAX`, `RAX`, `MM0`, `XMM0`, `YMM0`, `ZMM0`, `ES` + + ### Examples: + + ```python + from iced_x86 import * + + info = RegisterInfo(Register.GS) + assert info.base == Register.ES + info = RegisterInfo(Register.RDX) + assert info.base == Register.RAX + info = RegisterInfo(Register.XMM13) + assert info.base == Register.XMM0 + info = RegisterInfo(Register.YMM13) + assert info.base == Register.YMM0 + info = RegisterInfo(Register.ZMM13) + assert info.base == Register.ZMM0 + ``` + """ + ... @property - def number(self) -> int: ... + def number(self) -> int: + """ + int: The register number (index) relative to `RegisterInfo.base`, eg. 0-15, or 0-31, or if 8-bit GPR, 0-19 + + ### Examples: + + ```python + from iced_x86 import * + + info = RegisterInfo(Register.GS) + assert info.number == 5 + info = RegisterInfo(Register.RDX) + assert info.number == 2 + info = RegisterInfo(Register.XMM13) + assert info.number == 13 + info = RegisterInfo(Register.YMM13) + assert info.number == 13 + info = RegisterInfo(Register.ZMM13) + assert info.number == 13 + ``` + """ + ... @property - def full_register(self) -> Register: ... + def full_register(self) -> Register: + """ + `Register`: The full register that this one is a part of, eg. `CL`/`CH`/`CX`/`ECX`/`RCX` -> `RCX`, `XMM11`/`YMM11`/`ZMM11` -> `ZMM11` + + ### Examples: + + ```python + from iced_x86 import * + + info = RegisterInfo(Register.GS) + assert info.full_register == Register.GS + info = RegisterInfo(Register.BH) + assert info.full_register == Register.RBX + info = RegisterInfo(Register.DX) + assert info.full_register == Register.RDX + info = RegisterInfo(Register.ESP) + assert info.full_register == Register.RSP + info = RegisterInfo(Register.RCX) + assert info.full_register == Register.RCX + info = RegisterInfo(Register.XMM3) + assert info.full_register == Register.ZMM3 + info = RegisterInfo(Register.YMM3) + assert info.full_register == Register.ZMM3 + info = RegisterInfo(Register.ZMM3) + assert info.full_register == Register.ZMM3 + ``` + """ + ... @property - def full_register32(self) -> Register: ... + def full_register32(self) -> Register: + """ + `Register`: Gets the full register that this one is a part of, except if it's a GPR in which case the 32-bit register is returned, + eg. `CL`/`CH`/`CX`/`ECX`/`RCX` -> `ECX`, `XMM11`/`YMM11`/`ZMM11` -> `ZMM11` + + ### Examples: + + ```python + from iced_x86 import * + + info = RegisterInfo(Register.GS) + assert info.full_register32 == Register.GS + info = RegisterInfo(Register.BH) + assert info.full_register32 == Register.EBX + info = RegisterInfo(Register.DX) + assert info.full_register32 == Register.EDX + info = RegisterInfo(Register.ESP) + assert info.full_register32 == Register.ESP + info = RegisterInfo(Register.RCX) + assert info.full_register32 == Register.ECX + info = RegisterInfo(Register.XMM3) + assert info.full_register32 == Register.ZMM3 + info = RegisterInfo(Register.YMM3) + assert info.full_register32 == Register.ZMM3 + info = RegisterInfo(Register.ZMM3) + assert info.full_register32 == Register.ZMM3 + ``` + """ + ... @property - def size(self) -> int: ... + def size(self) -> int: + """ + int: Size of the register in bytes + + ### Examples: + + ```python + from iced_x86 import * + + info = RegisterInfo(Register.GS) + assert info.size == 2 + info = RegisterInfo(Register.BH) + assert info.size == 1 + info = RegisterInfo(Register.DX) + assert info.size == 2 + info = RegisterInfo(Register.ESP) + assert info.size == 4 + info = RegisterInfo(Register.RCX) + assert info.size == 8 + info = RegisterInfo(Register.XMM3) + assert info.size == 16 + info = RegisterInfo(Register.YMM3) + assert info.size == 32 + info = RegisterInfo(Register.ZMM3) + assert info.size == 64 + ``` + """ + ... class RegisterExt: + """`Register` enum extension methods, see also `RegisterInfo`""" @staticmethod - def info(register: Register) -> RegisterInfo: ... + def info(register: Register) -> RegisterInfo: + """ + Gets register info + + ### Args: + + - `register` (`Register`): Enum value + + ### Returns: + + - `RegisterInfo`: Register info + + ### Examples: + + ```python + from iced_x86 import * + + info = RegisterExt.info(Register.EAX) + assert info.size == 4 + ``` + """ + ... @staticmethod - def base(register: Register) -> Register: ... + def base(register: Register) -> Register: + """ + Gets the base register, eg. `AL`, `AX`, `EAX`, `RAX`, `MM0`, `XMM0`, `YMM0`, `ZMM0`, `ES` + + ### Args: + + - `register` (`Register`): Enum value + + ### Returns: + + - `Register`: Base register + + ### Examples: + + ```python + from iced_x86 import * + + assert RegisterExt.base(Register.GS) == Register.ES + assert RegisterExt.base(Register.SIL) == Register.AL + assert RegisterExt.base(Register.SP) == Register.AX + assert RegisterExt.base(Register.R13D) == Register.EAX + assert RegisterExt.base(Register.RBP) == Register.RAX + assert RegisterExt.base(Register.MM6) == Register.MM0 + assert RegisterExt.base(Register.XMM28) == Register.XMM0 + assert RegisterExt.base(Register.YMM12) == Register.YMM0 + assert RegisterExt.base(Register.ZMM31) == Register.ZMM0 + assert RegisterExt.base(Register.K3) == Register.K0 + assert RegisterExt.base(Register.BND1) == Register.BND0 + assert RegisterExt.base(Register.ST7) == Register.ST0 + assert RegisterExt.base(Register.CR8) == Register.CR0 + assert RegisterExt.base(Register.DR6) == Register.DR0 + assert RegisterExt.base(Register.TR3) == Register.TR0 + assert RegisterExt.base(Register.RIP) == Register.EIP + ``` + """ + ... @staticmethod - def number(register: Register) -> int: ... + def number(register: Register) -> int: + """ + The register number (index) relative to `RegisterExt.base`, eg. 0-15, or 0-31, or if 8-bit GPR, 0-19 + + ### Args: + + - `register` (`Register`): Enum value + + ### Returns: + + - int: Register number (index) relative to the base register + + ### Examples: + + ```python + from iced_x86 import * + + assert RegisterExt.number(Register.GS) == 5 + assert RegisterExt.number(Register.SIL) == 10 + assert RegisterExt.number(Register.SP) == 4 + assert RegisterExt.number(Register.R13D) == 13 + assert RegisterExt.number(Register.RBP) == 5 + assert RegisterExt.number(Register.MM6) == 6 + assert RegisterExt.number(Register.XMM28) == 28 + assert RegisterExt.number(Register.YMM12) == 12 + assert RegisterExt.number(Register.ZMM31) == 31 + assert RegisterExt.number(Register.K3) == 3 + assert RegisterExt.number(Register.BND1) == 1 + assert RegisterExt.number(Register.ST7) == 7 + assert RegisterExt.number(Register.CR8) == 8 + assert RegisterExt.number(Register.DR6) == 6 + assert RegisterExt.number(Register.TR3) == 3 + assert RegisterExt.number(Register.RIP) == 1 + ``` + """ + ... @staticmethod - def full_register(register: Register) -> Register: ... + def full_register(register: Register) -> Register: + """ + Gets the full register that this one is a part of, eg. `CL`/`CH`/`CX`/`ECX`/`RCX` -> `RCX`, `XMM11`/`YMM11`/`ZMM11` -> `ZMM11` + + ### Args: + + - `register` (`Register`): Enum value + + ### Returns: + + - `Register`: Full register (64-bit GPRs) + + ### Examples: + + ```python + from iced_x86 import * + + assert RegisterExt.full_register(Register.GS) == Register.GS + assert RegisterExt.full_register(Register.SIL) == Register.RSI + assert RegisterExt.full_register(Register.SP) == Register.RSP + assert RegisterExt.full_register(Register.R13D) == Register.R13 + assert RegisterExt.full_register(Register.RBP) == Register.RBP + assert RegisterExt.full_register(Register.MM6) == Register.MM6 + assert RegisterExt.full_register(Register.XMM10) == Register.ZMM10 + assert RegisterExt.full_register(Register.YMM10) == Register.ZMM10 + assert RegisterExt.full_register(Register.ZMM10) == Register.ZMM10 + assert RegisterExt.full_register(Register.K3) == Register.K3 + assert RegisterExt.full_register(Register.BND1) == Register.BND1 + assert RegisterExt.full_register(Register.ST7) == Register.ST7 + assert RegisterExt.full_register(Register.CR8) == Register.CR8 + assert RegisterExt.full_register(Register.DR6) == Register.DR6 + assert RegisterExt.full_register(Register.TR3) == Register.TR3 + assert RegisterExt.full_register(Register.RIP) == Register.RIP + ``` + """ + ... @staticmethod - def full_register32(register: Register) -> Register: ... + def full_register32(register: Register) -> Register: + """ + Gets the full register that this one is a part of, except if it's a GPR in which case the 32-bit register is returned, + eg. `CL`/`CH`/`CX`/`ECX`/`RCX` -> `ECX`, `XMM11`/`YMM11`/`ZMM11` -> `ZMM11` + + ### Args: + + - `register` (`Register`): Enum value + + ### Returns: + + - `Register`: Full register (32-bit GPRs) + + ### Examples: + + ```python + from iced_x86 import * + + assert RegisterExt.full_register32(Register.GS) == Register.GS + assert RegisterExt.full_register32(Register.SIL) == Register.ESI + assert RegisterExt.full_register32(Register.SP) == Register.ESP + assert RegisterExt.full_register32(Register.R13D) == Register.R13D + assert RegisterExt.full_register32(Register.RBP) == Register.EBP + assert RegisterExt.full_register32(Register.MM6) == Register.MM6 + assert RegisterExt.full_register32(Register.XMM10) == Register.ZMM10 + assert RegisterExt.full_register32(Register.YMM10) == Register.ZMM10 + assert RegisterExt.full_register32(Register.ZMM10) == Register.ZMM10 + assert RegisterExt.full_register32(Register.K3) == Register.K3 + assert RegisterExt.full_register32(Register.BND1) == Register.BND1 + assert RegisterExt.full_register32(Register.ST7) == Register.ST7 + assert RegisterExt.full_register32(Register.CR8) == Register.CR8 + assert RegisterExt.full_register32(Register.DR6) == Register.DR6 + assert RegisterExt.full_register32(Register.TR3) == Register.TR3 + assert RegisterExt.full_register32(Register.RIP) == Register.RIP + ``` + """ + ... @staticmethod - def size(register: Register) -> int: ... + def size(register: Register) -> int: + """ + Gets the size of the register in bytes + + ### Args: + + - `register` (`Register`): Enum value + + ### Returns: + + - int: Size of the register in bytes + + ### Examples: + + ```python + from iced_x86 import * + + assert RegisterExt.size(Register.GS) == 2 + assert RegisterExt.size(Register.SIL) == 1 + assert RegisterExt.size(Register.SP) == 2 + assert RegisterExt.size(Register.R13D) == 4 + assert RegisterExt.size(Register.RBP) == 8 + assert RegisterExt.size(Register.MM6) == 8 + assert RegisterExt.size(Register.XMM10) == 16 + assert RegisterExt.size(Register.YMM10) == 32 + assert RegisterExt.size(Register.ZMM10) == 64 + assert RegisterExt.size(Register.K3) == 8 + assert RegisterExt.size(Register.BND1) == 16 + assert RegisterExt.size(Register.ST7) == 10 + assert RegisterExt.size(Register.CR8) == 8 + assert RegisterExt.size(Register.DR6) == 8 + assert RegisterExt.size(Register.TR3) == 4 + assert RegisterExt.size(Register.RIP) == 8 + ``` + """ + ... @staticmethod - def is_segment_register(register: Register) -> bool: ... + def is_segment_register(register: Register) -> bool: + """ + Checks if it's a segment register (`ES`, `CS`, `SS`, `DS`, `FS`, `GS`) + + ### Args: + + - `register` (`Register`): Enum value + + ### Returns: + + - bool: `True` if it's a segment register + + ### Examples: + + ```python + from iced_x86 import * + + assert RegisterExt.is_segment_register(Register.GS) + assert not RegisterExt.is_segment_register(Register.RCX) + ``` + """ + ... @staticmethod - def is_gpr(register: Register) -> bool: ... + def is_gpr(register: Register) -> bool: + """ + Checks if it's a general purpose register (`AL`-`R15L`, `AX`-`R15W`, `EAX`-`R15D`, `RAX`-`R15`) + + ### Args: + + - `register` (`Register`): Enum value + + ### Returns: + + - bool: `True` if it's a general purpose register + + ### Examples: + + ```python + from iced_x86 import * + + assert not RegisterExt.is_gpr(Register.GS) + assert RegisterExt.is_gpr(Register.CH) + assert RegisterExt.is_gpr(Register.DX) + assert RegisterExt.is_gpr(Register.R13D) + assert RegisterExt.is_gpr(Register.RSP) + assert not RegisterExt.is_gpr(Register.XMM0) + ``` + """ + ... @staticmethod - def is_gpr8(register: Register) -> bool: ... + def is_gpr8(register: Register) -> bool: + """ + Checks if it's an 8-bit general purpose register (`AL`-`R15L`) + + ### Args: + + - `register` (`Register`): Enum value + + ### Returns: + + - bool: `True` if it's an 8-bit general purpose register + + ### Examples: + + ```python + from iced_x86 import * + + assert not RegisterExt.is_gpr8(Register.GS) + assert RegisterExt.is_gpr8(Register.CH) + assert not RegisterExt.is_gpr8(Register.DX) + assert not RegisterExt.is_gpr8(Register.R13D) + assert not RegisterExt.is_gpr8(Register.RSP) + assert not RegisterExt.is_gpr8(Register.XMM0) + ``` + """ + ... @staticmethod - def is_gpr16(register: Register) -> bool: ... + def is_gpr16(register: Register) -> bool: + """ + Checks if it's a 16-bit general purpose register (`AX`-`R15W`) + + ### Args: + + - `register` (`Register`): Enum value + + ### Returns: + + - bool: `True` if it's a 16-bit general purpose register + + ### Examples: + + ```python + from iced_x86 import * + + assert not RegisterExt.is_gpr16(Register.GS) + assert not RegisterExt.is_gpr16(Register.CH) + assert RegisterExt.is_gpr16(Register.DX) + assert not RegisterExt.is_gpr16(Register.R13D) + assert not RegisterExt.is_gpr16(Register.RSP) + assert not RegisterExt.is_gpr16(Register.XMM0) + ``` + """ + ... @staticmethod - def is_gpr32(register: Register) -> bool: ... + def is_gpr32(register: Register) -> bool: + """ + Checks if it's a 32-bit general purpose register (`EAX`-`R15D`) + + ### Args: + + - `register` (`Register`): Enum value + + ### Returns: + + - bool: `True` if it's a 32-bit general purpose register + + ### Examples: + + ```python + from iced_x86 import * + + assert not RegisterExt.is_gpr32(Register.GS) + assert not RegisterExt.is_gpr32(Register.CH) + assert not RegisterExt.is_gpr32(Register.DX) + assert RegisterExt.is_gpr32(Register.R13D) + assert not RegisterExt.is_gpr32(Register.RSP) + assert not RegisterExt.is_gpr32(Register.XMM0) + ``` + """ + ... @staticmethod - def is_gpr64(register: Register) -> bool: ... + def is_gpr64(register: Register) -> bool: + """ + Checks if it's a 64-bit general purpose register (`RAX`-`R15`) + + ### Args: + + - `register` (`Register`): Enum value + + ### Returns: + + - bool: `True` if it's a 64-bit general purpose register + + ### Examples: + + ```python + from iced_x86 import * + + assert not RegisterExt.is_gpr64(Register.GS) + assert not RegisterExt.is_gpr64(Register.CH) + assert not RegisterExt.is_gpr64(Register.DX) + assert not RegisterExt.is_gpr64(Register.R13D) + assert RegisterExt.is_gpr64(Register.RSP) + assert not RegisterExt.is_gpr64(Register.XMM0) + ``` + """ + ... @staticmethod - def is_xmm(register: Register) -> bool: ... + def is_xmm(register: Register) -> bool: + """ + Checks if it's a 128-bit vector register (`XMM0`-`XMM31`) + + ### Args: + + - `register` (`Register`): Enum value + + ### Returns: + + - bool: `True` if it's an XMM register + + ### Examples: + + ```python + from iced_x86 import * + + assert not RegisterExt.is_xmm(Register.R13D) + assert not RegisterExt.is_xmm(Register.RSP) + assert RegisterExt.is_xmm(Register.XMM0) + assert not RegisterExt.is_xmm(Register.YMM0) + assert not RegisterExt.is_xmm(Register.ZMM0) + ``` + """ + ... @staticmethod - def is_ymm(register: Register) -> bool: ... + def is_ymm(register: Register) -> bool: + """ + Checks if it's a 256-bit vector register (`YMM0`-`YMM31`) + + ### Args: + + - `register` (`Register`): Enum value + + ### Returns: + + - bool: `True` if it's a YMM register + + ### Examples: + + ```python + from iced_x86 import * + + assert not RegisterExt.is_ymm(Register.R13D) + assert not RegisterExt.is_ymm(Register.RSP) + assert not RegisterExt.is_ymm(Register.XMM0) + assert RegisterExt.is_ymm(Register.YMM0) + assert not RegisterExt.is_ymm(Register.ZMM0) + ``` + """ + ... @staticmethod - def is_zmm(register: Register) -> bool: ... + def is_zmm(register: Register) -> bool: + """ + Checks if it's a 512-bit vector register (`ZMM0`-`ZMM31`) + + ### Args: + + - `register` (`Register`): Enum value + + ### Returns: + + - bool: `True` if it's a ZMM register + + ### Examples: + + ```python + from iced_x86 import * + + assert not RegisterExt.is_zmm(Register.R13D) + assert not RegisterExt.is_zmm(Register.RSP) + assert not RegisterExt.is_zmm(Register.XMM0) + assert not RegisterExt.is_zmm(Register.YMM0) + assert RegisterExt.is_zmm(Register.ZMM0) + ``` + """ + ... @staticmethod - def is_vector_register(register: Register) -> bool: ... + def is_vector_register(register: Register) -> bool: + """ + Checks if it's an `XMM`, `YMM` or `ZMM` register + + ### Args: + + - `register` (`Register`): Enum value + + ### Returns: + + - bool: `True` if it's a vector register + + ### Examples: + + ```python + from iced_x86 import * + + assert not RegisterExt.is_vector_register(Register.R13D) + assert not RegisterExt.is_vector_register(Register.RSP) + assert RegisterExt.is_vector_register(Register.XMM0) + assert RegisterExt.is_vector_register(Register.YMM0) + assert RegisterExt.is_vector_register(Register.ZMM0) + ``` + """ + ... @staticmethod - def is_ip(register: Register) -> bool: ... + def is_ip(register: Register) -> bool: + """ + Checks if it's `EIP`/`RIP` + + ### Args: + + - `register` (`Register`): Enum value + + ### Returns: + + - bool: `True` if it's `EIP`/`RIP` + + ### Examples: + + ```python + from iced_x86 import * + + assert RegisterExt.is_ip(Register.EIP) + assert RegisterExt.is_ip(Register.RIP) + ``` + """ + ... @staticmethod - def is_k(register: Register) -> bool: ... + def is_k(register: Register) -> bool: + """ + Checks if it's an opmask register (`K0`-`K7`) + + ### Args: + + - `register` (`Register`): Enum value + + ### Returns: + + - bool: `True` if it's an opmask register + + ### Examples: + + ```python + from iced_x86 import * + + assert not RegisterExt.is_k(Register.R13D) + assert RegisterExt.is_k(Register.K3) + ``` + """ + ... @staticmethod - def is_cr(register: Register) -> bool: ... + def is_cr(register: Register) -> bool: + """ + Checks if it's a control register (`CR0`-`CR15`) + + ### Args: + + - `register` (`Register`): Enum value + + ### Returns: + + - bool: `True` if it's a control register + + ### Examples: + + ```python + from iced_x86 import * + + assert not RegisterExt.is_cr(Register.R13D) + assert RegisterExt.is_cr(Register.CR3) + ``` + """ + ... @staticmethod - def is_dr(register: Register) -> bool: ... + def is_dr(register: Register) -> bool: + """ + Checks if it's a debug register (`DR0`-`DR15`) + + ### Args: + + - `register` (`Register`): Enum value + + ### Returns: + + - bool: `True` if it's a debug register + + ### Examples: + + ```python + from iced_x86 import * + + assert not RegisterExt.is_dr(Register.R13D) + assert RegisterExt.is_dr(Register.DR3) + ``` + """ + ... @staticmethod - def is_tr(register: Register) -> bool: ... + def is_tr(register: Register) -> bool: + """ + Checks if it's a test register (`TR0`-`TR7`) + + ### Args: + + - `register` (`Register`): Enum value + + ### Returns: + + - bool: `True` if it's a test register + + ### Examples: + + ```python + from iced_x86 import * + + assert not RegisterExt.is_tr(Register.R13D) + assert RegisterExt.is_tr(Register.TR3) + ``` + """ + ... @staticmethod - def is_st(register: Register) -> bool: ... + def is_st(register: Register) -> bool: + """ + Checks if it's an FPU stack register (`ST0`-`ST7`) + + ### Args: + + - `register` (`Register`): Enum value + + ### Returns: + + - bool: `True` if it's an FPU register + + ### Examples: + + ```python + from iced_x86 import * + + assert not RegisterExt.is_st(Register.R13D) + assert RegisterExt.is_st(Register.ST3) + ``` + """ + ... @staticmethod - def is_bnd(register: Register) -> bool: ... + def is_bnd(register: Register) -> bool: + """ + Checks if it's a bound register (`BND0`-`BND3`) + + ### Args: + + - `register` (`Register`): Enum value + + ### Returns: + + - bool: `True` if it's a bnd register + + ### Examples: + + ```python + from iced_x86 import * + + assert not RegisterExt.is_bnd(Register.R13D) + assert RegisterExt.is_bnd(Register.BND3) + ``` + """ + ... @staticmethod - def is_mm(register: Register) -> bool: ... + def is_mm(register: Register) -> bool: + """ + Checks if it's an MMX register (`MM0`-`MM7`) + + ### Args: + + - `register` (`Register`): Enum value + + ### Returns: + + - bool: `True` if it's an mmx register + + ### Examples: + + ```python + from iced_x86 import * + + assert not RegisterExt.is_mm(Register.R13D) + assert RegisterExt.is_mm(Register.MM3) + ``` + """ + ... @staticmethod - def is_tmm(register: Register) -> bool: ... + def is_tmm(register: Register) -> bool: + """ + Checks if it's a tile register (`TMM0`-`TMM7`) + + ### Args: + + - `register` (`Register`): Enum value + + ### Returns: + + - bool: `True` if it's a tmm register + + ### Examples: + + ```python + from iced_x86 import * + + assert not RegisterExt.is_tmm(Register.R13D) + assert RegisterExt.is_tmm(Register.TMM3) + ``` + """ + ... diff --git a/src/rust/iced-x86-py/src/instruction.rs b/src/rust/iced-x86-py/src/instruction.rs index 1b9252007..db9735e49 100644 --- a/src/rust/iced-x86-py/src/instruction.rs +++ b/src/rust/iced-x86-py/src/instruction.rs @@ -363,8 +363,7 @@ impl Instruction { /// You can also call `len(instr)` to get this value. /// /// Note: - /// This is just informational. If you modify the instruction or create a new one, - /// this method could return the wrong value. + /// This is just informational. If you modify the instruction or create a new one, this method could return the wrong value. #[getter] fn len(&self) -> usize { self.instr.len()