diff options
| author | iximeow <me@iximeow.net> | 2026-04-12 01:03:47 +0000 |
|---|---|---|
| committer | iximeow <me@iximeow.net> | 2026-05-25 00:59:27 +0000 |
| commit | a049351c5d512710f557ffb45ee6391fc86a3dc6 (patch) | |
| tree | 17040c4c95f9361de271fb1ad874c3a71d2b0e9d /src | |
| parent | 6c32405ca9930f393d8ca45d22df1b5a1c7c8653 (diff) | |
fix table management instructions' ({l,s}{g,i,l}dt) mem_size
these instructions, it turns out, have fixed operand size based on CPU
execution mode and regardless of prefixes. good to know!
Diffstat (limited to 'src')
| -rw-r--r-- | src/long_mode/mod.rs | 11 | ||||
| -rw-r--r-- | src/protected_mode/mod.rs | 15 | ||||
| -rw-r--r-- | src/real_mode/mod.rs | 12 |
3 files changed, 26 insertions, 12 deletions
diff --git a/src/long_mode/mod.rs b/src/long_mode/mod.rs index 2971313..4288eb9 100644 --- a/src/long_mode/mod.rs +++ b/src/long_mode/mod.rs @@ -8243,7 +8243,7 @@ fn read_operands< } else { instruction.opcode = Opcode::SGDT; instruction.operand_count = 1; - instruction.mem_size = 63; + instruction.mem_size = 10; instruction.operands[0] = read_E(words, instruction, modrm, bank, sink)?; } } else if r == 1 { @@ -8298,7 +8298,7 @@ fn read_operands< } else { instruction.opcode = Opcode::SIDT; instruction.operand_count = 1; - instruction.mem_size = 63; + instruction.mem_size = 10; instruction.operands[0] = read_E(words, instruction, modrm, bank, sink)?; } } else if r == 2 { @@ -8337,7 +8337,10 @@ fn read_operands< } else { instruction.opcode = Opcode::LGDT; instruction.operand_count = 1; - instruction.mem_size = 63; + // quoth SDM: + // > In 64-bit mode, the operand size is fixed at 8+2 bytes. The instruction + // > stores an 8-byte base and a 2-byte limit. + instruction.mem_size = 10; instruction.operands[0] = read_E(words, instruction, modrm, bank, sink)?; } } else if r == 3 { @@ -8401,7 +8404,7 @@ fn read_operands< } else { instruction.opcode = Opcode::LIDT; instruction.operand_count = 1; - instruction.mem_size = 63; + instruction.mem_size = 10; instruction.operands[0] = read_E(words, instruction, modrm, bank, sink)?; } } else if r == 4 { diff --git a/src/protected_mode/mod.rs b/src/protected_mode/mod.rs index 6701071..89c5dfd 100644 --- a/src/protected_mode/mod.rs +++ b/src/protected_mode/mod.rs @@ -8042,7 +8042,7 @@ fn read_operands< } else { instruction.opcode = Opcode::SGDT; instruction.operand_count = 1; - instruction.mem_size = 63; + instruction.mem_size = 6; instruction.operands[0] = read_E(words, instruction, modrm, bank, sink)?; } } else if r == 1 { @@ -8097,7 +8097,11 @@ fn read_operands< } else { instruction.opcode = Opcode::SIDT; instruction.operand_count = 1; - instruction.mem_size = 63; + // quoth SDM: + // > In non-64-bit modes, the 16-bit limit field of the register is stored in + // > the low 2 bytes of the memory location and the 32-bit base address is + // > stored in the high 4 bytes. + instruction.mem_size = 6; instruction.operands[0] = read_E(words, instruction, modrm, bank, sink)?; } } else if r == 2 { @@ -8136,7 +8140,10 @@ fn read_operands< } else { instruction.opcode = Opcode::LGDT; instruction.operand_count = 1; - instruction.mem_size = 63; + // quoth SDM: + // > In legacy or compatibility mode, the destination operand is a 6-byte + // > memory location. + instruction.mem_size = 6; instruction.operands[0] = read_E(words, instruction, modrm, bank, sink)?; } } else if r == 3 { @@ -8200,7 +8207,7 @@ fn read_operands< } else { instruction.opcode = Opcode::LIDT; instruction.operand_count = 1; - instruction.mem_size = 63; + instruction.mem_size = 6; instruction.operands[0] = read_E(words, instruction, modrm, bank, sink)?; } } else if r == 4 { diff --git a/src/real_mode/mod.rs b/src/real_mode/mod.rs index 7ac4c2e..559cac3 100644 --- a/src/real_mode/mod.rs +++ b/src/real_mode/mod.rs @@ -8087,7 +8087,7 @@ fn read_operands< } else { instruction.opcode = Opcode::SGDT; instruction.operand_count = 1; - instruction.mem_size = 63; + instruction.mem_size = 6; instruction.operands[0] = read_E(words, instruction, modrm, bank, sink)?; } } else if r == 1 { @@ -8142,7 +8142,11 @@ fn read_operands< } else { instruction.opcode = Opcode::SIDT; instruction.operand_count = 1; - instruction.mem_size = 63; + // quoth SDM: + // > In non-64-bit modes, the 16-bit limit field of the register is stored in + // > the low 2 bytes of the memory location and the 32-bit base address is + // > stored in the high 4 bytes. + instruction.mem_size = 6; instruction.operands[0] = read_E(words, instruction, modrm, bank, sink)?; } } else if r == 2 { @@ -8181,7 +8185,7 @@ fn read_operands< } else { instruction.opcode = Opcode::LGDT; instruction.operand_count = 1; - instruction.mem_size = 63; + instruction.mem_size = 6; instruction.operands[0] = read_E(words, instruction, modrm, bank, sink)?; } } else if r == 3 { @@ -8245,7 +8249,7 @@ fn read_operands< } else { instruction.opcode = Opcode::LIDT; instruction.operand_count = 1; - instruction.mem_size = 63; + instruction.mem_size = 6; instruction.operands[0] = read_E(words, instruction, modrm, bank, sink)?; } } else if r == 4 { |
