
1. Mod R/M Byte Encoding Mechanism
1.1 Basic Structure
The Mod R/M byte is a core component of x86 instruction encoding, dividing the 8 bits into three fields:
- Mod (2 bits): Specifies the addressing mode and offset type
- Reg/Opcode (3 bits): Specifies the register or opcode extension
- R/M (3 bits): Specifies the second register or memory addressing mode
Mod R/M byte structure:
┌───┬───┬───┬───┬───┬───┬───┬───┐
│ 7 │ 6 │ 5 │ 4 │ 3 │ 2 │ 1 │ 0 │
├───┼───┼───┼───┼───┼───┼───┼───┤
│ Mod │ Reg │ R/M │
└───┴───┴───┴───┴───┴───┴───┴───┘
1.2 Meaning of Mod Field
- 00: No offset (except when R/M=110, which uses a 16-bit direct address)
- 01: 8-bit signed extended offset
- 10: 16-bit offset
- 11: Register mode (no memory access)
2. Detailed Memory Addressing Modes
2.1 16-bit Addressing Mode
Addressing method when Mod=00:
; Example code demonstrating various addressing modes
section .data
myWord dw 1234h
section .text
; 1. Base + Index addressing
mov ax, [bx+si] ; Mod=00, R/M=000
mov [bx+di], cx ; Mod=00, R/M=001
; 2. Base addressing
mov dx, [bp+si] ; Mod=00, R/M=010
mov [bp+di], bx ; Mod=00, R/M=011
; 3. Index addressing
mov ax, [si] ; Mod=00, R/M=100
mov [di], bx ; Mod=00, R/M=101
; 4. Direct addressing
mov ax, [myWord] ; Mod=00, R/M=110, followed by 16-bit offset
mov cx, [bx] ; Mod=00, R/M=111
2.2 Addressing Modes with Offset
; Mod=01 (8-bit offset) example
mov [bx+2], ax ; Machine code: 89 47 02
mov byte [si-5], 10h ; 8-bit negative offset
; Mod=10 (16-bit offset) example
mov [bp+100h], cx ; 16-bit positive offset
mov word [di-200h], 1234h ; 16-bit negative offset
3. Operand Size Prefix
3.1 Function and Significance
The operand size prefix (66H) is used to switch operand sizes between 16-bit and 32-bit modes:
; Using 32-bit operand in 16-bit mode
bits 16
db 66h ; Operand size prefix
mov eax, [ebx] ; 32-bit operation
; Using 16-bit operand in 32-bit mode
bits 32
db 66h
mov ax, [ebx] ; 16-bit operation
3.2 Practical Application Scenarios
section .data
array32 dd 1, 2, 3, 4
array16 dw 1, 2, 3, 4
section .text
global _start
_start:
; 16-bit operation in 32-bit mode
mov ebx, array16
db 66h ; Operand size prefix
mov ax, [ebx] ; Read 16-bit data
; Cross-mode data access
mov esi, array32
db 66h
add word [esi], 100h ; 16-bit operation modifies 32-bit array
4. Analysis of MOV Instruction Encoding Examples
4.1 Register-Memory Transfer
section .data
var8 db 12h
var16 dw 1234h
buffer times 10 db 0
section .text
; Memory to register
mov al, [var8] ; 8A 06 [offset]
mov bx, [var16] ; 8B 1E [offset]
; Register to memory
mov [var8], cl ; 88 0E [offset]
mov [var16], dx ; 89 16 [offset]
; Complex addressing mode
mov [bx+si], al ; 88 00
mov ax, [bp+di+2] ; 8B 43 02
4.2 Immediate Value Operations
; Immediate value to register
mov al, 5 ; B0 05
mov bx, 1000h ; BB 00 10
; Immediate value to memory
mov byte [si], 10h ; C6 04 10
mov word [bx], 1234h; C7 07 34 12
; Storing immediate value with offset
mov word [bx+di+4], 5678h ; C7 41 04 78 56
5. High-Level Language Interface
5.1 C Language Calling Convention
; C function declaration: int add_numbers(int a, int b);
section .text
global add_numbers
add_numbers:
push bp
mov bp, sp
; Access parameters (16-bit mode)
mov ax, [bp+4] ; First parameter a
mov bx, [bp+6] ; Second parameter b
add ax, bx ; Calculate result
pop bp
ret
; Call C function from Assembly
extern printf
section .data
fmt db "Result: %d", 0Ah, 0
result dw 0
section .text
global _start
_start:
mov ax, 100
mov bx, 200
call add_numbers
mov [result], ax
; Call printf
push word [result]
push fmt
call printf
add sp, 4
5.2 Stack Frame Management
; Standard function prologue and epilogue
my_function:
; Prologue
push bp
mov bp, sp
sub sp, 4 ; Allocate space for local variables
; Local variables
mov word [bp-2], 0 ; local_var1
mov word [bp-4], 0 ; local_var2
; Function body
mov ax, [bp+4] ; Parameter1
mov [bp-2], ax
; Epilogue
mov sp, bp
pop bp
ret
6. Complete Example Program
section .data
array dw 100h, 200h, 300h, 400h
count equ 4
result dw 0
msg db "Sum: %d", 0Ah, 0
section .text
global _start
extern printf
; Function: Calculate sum of array
; Input: SI = array address, CX = number of elements
; Output: AX = total sum
array_sum:
push bp
mov bp, sp
push bx
push cx
push si
xor ax, ax ; Clear AX
mov bx, 0 ; Index
.sum_loop:
cmp bx, cx
jge .done
; Access array using base + index addressing
mov dx, [si+bx*2] ; Each element is 2 bytes
add ax, dx
inc bx
jmp .sum_loop
.done:
pop si
pop cx
pop bx
mov sp, bp
pop bp
ret
_start:
; Set up data segment
mov ax, @data
mov ds, ax
; Calculate sum of array
mov si, array
mov cx, count
call array_sum
mov [result], ax
; Display result (call C function)
push word [result]
push msg
call printf
add sp, 4
; Exit program
mov ax, 4C00h
int 21h
Conclusion
The Mod R/M byte encoding is a core reflection of the complexity of the x86 instruction set, supporting a rich variety of memory addressing modes. Understanding this encoding mechanism is crucial for:
- Manual assembly and disassembly: Accurately calculating instruction lengths and machine codes
- Code optimization: Choosing the most efficient addressing methods
- Cross-language programming: Achieving seamless interfaces between assembly and high-level languages
- System programming: Gaining deep insights into processor operation principles
The operand size prefix plays a key role in handling mixed-size data, especially important in modern protected mode programming.