x86 64架构汇编语言

5、保护模式下的寻址方式

1、课程目标

  • 理解实模式与保护模式的区别
  • 掌握各种内存寻址方式
  • 理解段寄存器的作用
  • 掌握有效地址计算

2、名词解释

术语 说明
实模式 16位地址模式(1MB)
保护模式 32/64位模式,内存保护
平坦模式 段基址为0的保护模式
有效地址 指令中计算出的地址
基址寄存器 地址计算的基础
变址寄存器 乘以比例因子的寄存器
比例因子 1, 2, 4, 8

3、代码实现

1. 寻址方式

.code
Addressing PROC
    ; 立即寻址
    mov eax, 12345678h     ; 立即数
    
    ; 寄存器寻址
    mov eax, ebx            ; 寄存器到寄存器
    
    ; 直接寻址
    mov eax, [00401000h]    ; 直接地址
    
    ; 寄存器间接寻址
    mov eax, [ebx]          ; [EBX]
    
    ; 基址+偏移寻址
    mov eax, [ebx + 100]    ; [EBX + disp]
    
    ; 变址寻址 (带比例因子)
    mov eax, [ecx*4]        ; [index * scale]
    
    ; 基址+变址
    mov eax, [ebx + ecx*4]  ; [base + index * scale]
    
    ; 基址+变址+偏移 (最复杂形式)
    mov eax, [ebx + ecx*4 + 100]
    
    ret
Addressing ENDP

2. 有效地址计算

.data
    array   dd  10, 20, 30, 40, 50

.code
ArrayAccess PROC
    ; 访问数组元素
    lea ebx, array          ; EBX = 数组基址
    mov ecx, 2              ; 索引 = 2
    
    ; 计算 array[2] 的地址
    ; 地址 = base + index * sizeof(element)
    mov eax, [ebx + ecx*4]  ; EAX = array[2] = 30
    
    ; 使用LEA计算地址
    lea edx, [ebx + ecx*4]  ; EDX = &array[2]
    
    ret
ArrayAccess ENDP

3. 结构体访问

#include <stdio.h>

typedef struct {
    int id;         // +0
    char name[32];  // +4
    int age;        // +36
} Person;

int main() {
    printf("=== 结构体寻址 ===\n\n");
    
    Person p = {1, "Alice", 25};
    int age;
    
    // 通过偏移访问成员
    __asm {
        lea ebx, p          // EBX = &p
        mov eax, [ebx + 36] // 访问 age (偏移36)
        mov age, eax
    }
    
    printf("年龄: %d\n", age);
    printf("偏移量: id=%d, name=%d, age=%d\n",
           offsetof(Person, id),
           offsetof(Person, name),
           offsetof(Person, age));
    
    return 0;
}

4、课后作业

4.1、作业1:数组遍历

用汇编实现数组求和。

4.2、作业2:结构体操作

定义一个结构体并用汇编访问其成员。