Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
en:multiasm:papc:chapter_6_6 [2025/07/31 12:17] – [Scale Index Base byte] ktokarzen:multiasm:papc:chapter_6_6 [2025/08/01 06:59] (current) – [Scale Index Base byte] ktokarz
Line 84: Line 84:
  
 The **segment override** prefix is used in the segmented mode of operation. It causes the instruction to access data placed in a segment other than the default. For example, the mov instruction accesses data in the segment pointed by DS, which can be changed to ES with a prefix. The **segment override** prefix is used in the segmented mode of operation. It causes the instruction to access data placed in a segment other than the default. For example, the mov instruction accesses data in the segment pointed by DS, which can be changed to ES with a prefix.
-<code>+<code asm>
 mov BYTE PTR [ebx], 5     ;DS as the default segment mov BYTE PTR [ebx], 5     ;DS as the default segment
 mov BYTE PTR ES:[ebx], 5  ;ES segment override (results in appearance of the byte 0x26 as the prefix) mov BYTE PTR ES:[ebx], 5  ;ES segment override (results in appearance of the byte 0x26 as the prefix)
Line 99: Line 99:
  
 The **operand size** and **address size override** prefixes can change the default size of operands and addresses. For example, if the processor operates in 32-bit mode, using the 0x66 prefix changes the size of an operand to 16 bits, and using the 0x67 prefix changes the address encoding from 32 bits to 16 bits. To better understand the behaviour of prefixes, let us consider a simple instruction with different variants. Let's start with a 32-bit processor. The **operand size** and **address size override** prefixes can change the default size of operands and addresses. For example, if the processor operates in 32-bit mode, using the 0x66 prefix changes the size of an operand to 16 bits, and using the 0x67 prefix changes the address encoding from 32 bits to 16 bits. To better understand the behaviour of prefixes, let us consider a simple instruction with different variants. Let's start with a 32-bit processor.
-<code>+<code asm>
 mov BYTE PTR [ebx], 0x5   ;encoded as 0xC6, 0x03, 0x05 mov BYTE PTR [ebx], 0x5   ;encoded as 0xC6, 0x03, 0x05
 mov WORD PTR [ebx], 0x5   ;encoded as 0x66, 0xC7, 0x03, 0x05, 0x00  mov WORD PTR [ebx], 0x5   ;encoded as 0x66, 0xC7, 0x03, 0x05, 0x00 
Line 108: Line 108:
  
 The address override prefix (0x67) appears if we change the register to a 16-bit bx. The address override prefix (0x67) appears if we change the register to a 16-bit bx.
-<code>+<code asm>
 mov BYTE PTR [bx], 0x5   ;encoded as 0x67, 0xC6, 0x07, 0x05 mov BYTE PTR [bx], 0x5   ;encoded as 0x67, 0xC6, 0x07, 0x05
 mov WORD PTR [bx], 0x5   ;encoded as 0x67, 0x66, 0xC7, 0x07, 0x05, 0x00  mov WORD PTR [bx], 0x5   ;encoded as 0x67, 0x66, 0xC7, 0x07, 0x05, 0x00 
Line 115: Line 115:
  
 The same situation can be observed if we use a 32-bit address register (ebx) and assemble the same instructions for a 64-bit processor. The same situation can be observed if we use a 32-bit address register (ebx) and assemble the same instructions for a 64-bit processor.
-<code>+<code asm>
 mov BYTE PTR [ebx], 0x5   ;encoded as 0x67, 0xC6, 0x03, 0x05 mov BYTE PTR [ebx], 0x5   ;encoded as 0x67, 0xC6, 0x03, 0x05
 mov WORD PTR [ebx], 0x5   ;encoded as 0x67, 0x66, 0xC7, 0x03, 0x05, 0x00  mov WORD PTR [ebx], 0x5   ;encoded as 0x67, 0x66, 0xC7, 0x03, 0x05, 0x00 
Line 122: Line 122:
  
 While we use a native 64-bit address register in a 64-bit processor, the address size override prefix disappears. While we use a native 64-bit address register in a 64-bit processor, the address size override prefix disappears.
-<code>+<code asm>
 mov BYTE PTR [rbx], 0x5   ;encoded as 0xC6, 0x03, 0x05 mov BYTE PTR [rbx], 0x5   ;encoded as 0xC6, 0x03, 0x05
 mov WORD PTR [rbx], 0x5   ;encoded as 0x66, 0xC7, 0x03, 0x05, 0x00  mov WORD PTR [rbx], 0x5   ;encoded as 0x66, 0xC7, 0x03, 0x05, 0x00 
Line 141: Line 141:
 Bits R, X and B enable the use of new registers. Bits R, X and B enable the use of new registers.
  
-<code>+<code asm>
 mov BYTE PTR [r8], 0x5    ;encoded as 0x41, 0xC6, 0x00, 0x05 mov BYTE PTR [r8], 0x5    ;encoded as 0x41, 0xC6, 0x00, 0x05
 mov BYTE PTR [r9], 0x5    ;encoded as 0x41, 0xC6, 0x01, 0x05 mov BYTE PTR [r9], 0x5    ;encoded as 0x41, 0xC6, 0x01, 0x05
Line 199: Line 199:
  
 Let's look at some examples of instruction encoding. First, look at the data transfer between two registers. Let's look at some examples of instruction encoding. First, look at the data transfer between two registers.
-<code>+<code asm>
               ;                         MOD REG R/M   MOD               REG   R/M               ;                         MOD REG R/M   MOD               REG   R/M
 mov al, dl    ;encoded as 0x88, 0xD0    11  010 000   Register operand  DL    AL mov al, dl    ;encoded as 0x88, 0xD0    11  010 000   Register operand  DL    AL
Line 209: Line 209:
  
 Now, a few examples of indirect addressing without displacement. Now, a few examples of indirect addressing without displacement.
-<code>+<code asm>
               ;                         MOD REG R/M   MOD               REG   R/                  ;                         MOD REG R/M   MOD               REG   R/   
 mov dx,[si]   ;encoded as 0x8B, 0x14    00  010 100   Reg. only addr.   DX    [SI] mov dx,[si]   ;encoded as 0x8B, 0x14    00  010 100   Reg. only addr.   DX    [SI]
Line 218: Line 218:
  
 Now, a few examples of indirect addressing with displacement. Now, a few examples of indirect addressing with displacement.
-<code>+<code asm>
               ;                             MOD REG R/M   MOD              REG  R/M       Disp                 ;                             MOD REG R/M   MOD              REG  R/M       Disp  
 mov dx,[bp+62];encoded as 0x8B, 0x56, 0x3E  01  010 110   Reg.+disp addr.  DX   [BP+disp] 0x3E mov dx,[bp+62];encoded as 0x8B, 0x56, 0x3E  01  010 110   Reg.+disp addr.  DX   [BP+disp] 0x3E
Line 308: Line 308:
 In the tables {{ref>SIB_index}} and {{ref>SIB_index64}}, the * means that there is no index register encoded in the instruction. It results in base-only or direct addressing. In the tables {{ref>SIB_index}} and {{ref>SIB_index64}}, the * means that there is no index register encoded in the instruction. It results in base-only or direct addressing.
  
-Let's look at some code examples, considering the 32-bit version first.+Let's look at some code examples, considering the 32-bit version first. In all instructions, there is a MOD R/M byte and an SIB byte. MOD R/M is identical for all instructions. REG field indicates eax register and the combination of MOD and R/M indicates that registers are specified with the SIB byte.
 <code asm> <code asm>
-mov eax, [ebx+ecx]     ;0x8B, 0x04, 0x0B +;MOD R/M (second byte) is 0x04 for all instructions: 
-mov eax, [ebx+ecx*2]   ;0x8B, 0x04, 0x4B +                       ;                    MOD REG R/M   REG  MOD & R/M 
-mov eax, [ebx+ecx*4]   ;0x8B, 0x04, 0x8B +                       ;                     00 000 100   eax  SIB is present 
-mov eax, [ebx+ecx*8]   ;0x8B, 0x04, 0xCB+ 
 +;SIB (third byte) is 0x0B, 0x4B, 0x8B or 0xCB: 
 +                       ;                  Scale Index Base  Scale Index Base 
 +mov eax, [ebx+ecx]     ;0x8B, 0x04, 0x0B     00   001  011     x1   ecx  ebx 
 +mov eax, [ebx+ecx*2]   ;0x8B, 0x04, 0x4B     01   001  011     x2   ecx  ebx 
 +mov eax, [ebx+ecx*4]   ;0x8B, 0x04, 0x8B     10   001  011     x4   ecx  ebx 
 +mov eax, [ebx+ecx*8]   ;0x8B, 0x04, 0xCB     11   001  011     x8   ecx  ebx
 </code> </code>
 +
 +And other examples for x64 processors. The SIB byte is extended with bits from the REX prefix. We'll start with the similar examples as shown for 32-bit machines.
 +
 +<code asm>
 +;REX prefix (first byte) is 0x48 for all instructions:
 +                       ;                                             0
 +                       ;                 +---+---+---+---+---+---+---+---+
 +                       ;                 | 0       0 | W | R | X | B |
 +                       ;                 +---+---+---+---+---+---+---+---+
 +                       ;                                         0
 +
 +;MOD R/M (second byte) is 0x04 for all instructions:
 +                       ;                    MOD R.REG R/M   REG  MOD & R/M
 +                       ;                     00 0.000 100   eax  SIB is present
 +
 +                       ;                        Scale X.Index B.Base  Scale Index Base
 +mov rax, [rbx+rcx]     ;0x48, 0x8B, 0x04, 0x0B     00   0.001  0.011     x1   rcx  rbx
 +mov rax, [rbx+rcx*2]   ;0x48, 0x8B, 0x04, 0x4B     01   0.001  0.011     x2   rcx  rbx
 +mov rax, [rbx+rcx*4]   ;0x48, 0x8B, 0x04, 0x8B     10   0.001  0.011     x4   rcx  rbx
 +mov rax, [rbx+rcx*8]   ;0x48, 0x8B, 0x04, 0xCB     11   0.001  0.011     x8   rcx  rbx
 +</code>
 +
 +If any of the new registers (R8-R15) is used in the instruction, it changes the bits in the REX prefix.
 +
 +<code asm>
 +                       ;                        Scale X.Index B.Base  Scale Index Base
 +mov rax, [r10+rcx]     ;0x49, 0x8B, 0x04, 0x0A     00   0.001  1.010     x1   rcx  r10
 +mov rax, [rbx+r11]     ;0x4A, 0x8B, 0x04, 0x1B     00   1.001  0.011     x1   r11  rbx
 +mov r12, [rbx+rcx]     ;0x4C, 0x8B, 0x24, 0x0B     10   0.001  0.011     x1   rcx  rbx
 +
 +                       ;Last instruction has the MOD R/M REG field extended 
 +                       ;by the R bit from the REX prefix.
 +                       ;                    MOD R.REG R/M   REG  MOD & R/M
 +                       ;                     00 1.100 100   r12  SIB is present
 +</code>
 +
 +Certainly, the presented examples do not exhaust all possible situations. For a more detailed explanation, please refer to the documentation by AMD((https://docs.amd.com/v/u/en-US/40332-PUB_4.08)), Intel((https://www.intel.com/content/www/us/en/developer/articles/technical/intel-sdm.html)), OSDev wiki((https://wiki.osdev.org/X86-64)) or other interesting sources mentioned at the bottom of this section.
 =====Displacement===== =====Displacement=====
 Displacement gives the offset for memory operands. Depending on the addressing mode, it can be the direct memory address or an additional offset added to the contents of the base, index register or both. Displacement can be 1, 2, or 4 bytes long. Some instructions allow using an 8-byte displacement. In these instructions, there is no immediate field. Displacement gives the offset for memory operands. Depending on the addressing mode, it can be the direct memory address or an additional offset added to the contents of the base, index register or both. Displacement can be 1, 2, or 4 bytes long. Some instructions allow using an 8-byte displacement. In these instructions, there is no immediate field.
en/multiasm/papc/chapter_6_6.1753964253.txt.gz · Last modified: 2025/07/31 12:17 by ktokarz
CC Attribution-Share Alike 4.0 International
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0