数据寻址
文章目录
一、寻址概述
运行的程序保存于主存储器,需要通过存储器地址访问程序的指令和数据 通过地址访问指令或数据的方法称为寻址方式
(Addressing Mod) 一条指令执行后,确定下一条执行指令的方法是指令寻址
。执行过程中,访问所需要操作的数据(操作数)的方法是数据寻址
。
IA-32 处理器除外设数据外的数据寻址方式有以下三类:
• 用常量表达的具体数值(立即数寻址)
• 用寄存器名表示的其中内容(寄存器寻址)
• 用存储器地址代表的保存的数据(存储器寻址)
二、数据寻址方式
(1)立即数寻址
1.立即数寻址定义
在立即数寻址(或立即寻址)方式中,指令需要的操作数紧跟在操作码之后作为指令机器代码的一部分,并随着处理器的取指操作从主存进入指令寄存器。
- 操作数用常量形式直接表达,从指令代码中立即得到,称之为立即数。
- 立即数寻址方式只用于指令的源操作数,在传送指令中常用来给寄存器和存储单元赋值。
2.立即数的形式
-
十六进制常数
00000000 B0 12 mov al, 12h
-
字符(ASCII码值)
00000002 B4 64 mov ah, 'd'
-
十进制负数(补码)
00000004 66|BB FFFF labl: mov bx, -1
-
符号常量
00000008 B9 00000040 mov ecx, const
-
表达式
0000000D BA 00000040 mov edx, const*4/type dvar
-
变量的偏移地址
00000012 BE 00000000 R mov esi, offset bvar
-
标号的偏移地址
00000017 BF 00000004 R mov edi, labl
代码段使用标号名代表其偏移地址
3.立即数的类型
立即数的类型由对应的寄存器或变量类型决定。
-
字节变量bvar类型
0000001C C6 05 00000000 R 4C mov bvar, 01001100b
-
双字变量dvar类型
00000023 C7 05 00000006 R 00000012 mov dvar+4, 12h
4.立即数寻址总结
- 立即数寻址
►操作数紧跟操作码,是机器代码的一部分
►操作数从指令代码中得到,即立即数(Immediate) - 立即数寻址方式只用于源操作数
►常用来给寄存器和存储单元赋值
►用常量形式直接表达
符号 | 含义 |
---|---|
i8 | 8位立即数 |
i16 | 16位立即数 |
i32 | 32位立即数 |
imm | 立即数 |
(2)寄存器寻址
1.寄存器寻址定义
指令的操作数存放在处理器的寄存器中,就是寄存器寻址方式。
- 操作数存放在处理器的内部寄存器中,用寄存器名表示它的内容
2.寄存器寻址形式
-
目的操作数是寄存器寻址
mov al, 12 mov bx, 12
-
源操作数是寄存器寻址
mov bvar, cl mov wvar, dx mov dvar, edx
-
源操作数和目的操作数均是寄存器寻址
mov al, ah mov bx, ax mov ebx, eax mov dx, ds mov es, dx
3.寄存器寻址语法错
mov edi,si
错误的原因是两个操作数的类型不匹配,因为 EDI 32 位寄存器SI 16 位寄存器, MOE 指令不允许把 16 位寄存器的数据传送到 32 位寄存器
4.寄存器寻址总结
- 寄存器寻址
►操作数存放在处理器的内部寄存器中
►用寄存器名表示它的内容 - 寄存器寻址方式简单快捷,最常使用
►绝大多数指令采用通用寄存器
►部分指令支持专用寄存器
(例如段寄存器)
符号 | 含义 |
---|---|
r8 | 8位寄存器 |
r16 | 16位寄存器 |
r32 | 32位寄存器 |
reg | 通用寄存器 |
(3)存储器寻址
1.存储器寻址概述
寻址主存中存储的操作数就称为存储器寻址方式,也称为主存寻址方式 编程时,存储器地址使用包含段选择器和偏移地址的逻辑地址。
-
段寄存器的默认和超越
绝大部分情况使用默认规定,无需表达:
►读取指令,一定是代码段CS
►堆栈操作,针对堆栈段SS
►读写数据,默认在数据段DS- 寻址存储器操作数时,段寄存器不用显式说明,数据就在默认的段中,一般是 DS 段寄存器指向的数据段;如果采用 EBP (BP)或ESP (SP) 作为基地址指针,则默认使用 SS 段寄存器指向堆栈段。
- 如果不使用默认的段选择器,则需要书写段超越指令前缀显式说明。段超越指令前缀是一种只能跟随在具有存储器操作数的指令之前的指令,其助记符是段寄存器名后跟英文冒号,
CS: SS: ES: FS: GS:
问存储器的方式 默认 可超越 偏移地址 取指令 CS 无 EIP 栈操作 SS 无 ESP 般数据访问(下列除外) DS CS ES SS FS GS 有效地址EA BP/ESP基址的数据访问 SS CS ES DS FS GS 有效地址EA 指令的源操作数 DS CS ES SS FS GS ESI 指令的目的操作数 ES 无 EDI -
偏移地址的组成
-
32位有效地址的组成
基址寄存器+变址寄存器×比例+位移量
-
16位有效地址的组成
基址寄存器+变址寄存器+位移量
-
2.存储器寻址方式
①存储器的直接寻址
有效地址只有位移量部分,直接包含在指令代码中,用变量名(或加中括号)表示偏移地址
►直接使用变量名表达:变量名
►变量名加或减一个常量:变量名+n 、变量名-n
►或者用中括号括起变量名:[变量名] 、变量名[n]
MOV ECX,COUNT
MOV ECX,[COUNT]
MOV ECX, DS:[405000H]
-
主存操作数常通过变量形式引用,一般不需要使用段超越前缀指令
-
源操作数和目的操作数均可以采用存储器操作数,但不能同时使用
这是因为绝大多数指令并不支持两个操作数都是存储单元。虽然高级语言将一个变量赋值给另一个变量很常见,但使用直接寻址访问变量,需要在指令代码中编码有效地址。如果编码两个地址,将导致指令代码过长;而指令执行时至少要访问两次主存,也使得指令功能较复杂,硬件实现也较困难。
②存储器的寄存器间接寻址
有效地址存放在寄存器中,就是采用寄存器间接寻址存储器操作数,使用英文中括号括起寄存器名表示寄存器间接寻址。
-
寄存器间接寻址未说明数据类型,寄存器间接寻址的数据由另一个操作数的寄存器或变量类型决定
mov edx,[ebx] ;双字量传送 mov cx,[esi] ;字量传送 mov [edi],al ;字节量传送
立即数也无类型,故需要显式说明
MOV [EBX],100 ;错误,数据类型不明确
mov byte ptr [ebx],100 ;正确:byte ptr说明是字节操作 mov word ptr [ebx],100 ;正确:word ptr说明是字操作 mov dword ptr[ebx],100 ;正确:dword ptr说明是双字操作
③存储器的寄存器相对寻址
有效地址是寄存器内容与位移量之和,寄存器要用中括号括起
mov esi,[ebx+4] ;位移量:4
mov edi,[ebp-08h] ;位移量:-08H
mov eax,count[esi] ;位移量:count
- 主存储器采用字节编址,地址的加减是以主存字节单元为单位
- 方便对数组的元素或字符串的字符进行操作
►数组(字符串)的首地址作为位移量
►寄存器赋值0,或者元素(字符)个数
►增减寄存器值指向不同的元素(字符)
寄存器相对寻址的多种表达形式
-
位移量:4,无类型
mov esi, [ebx+4]
mov esi, 4[ebx]
mov esi, [4][ebx]
-
位移量:count ,count定义的类型,count表示变量所在的偏移地址用作相对寻址的位移量
mov eax, count[esi]
mov eax, [esi+count]
mov eax, [count][esi]
④存储器的变址寻址
使用变址寄存器寻址操作数称为变址寻址,有效地址需要使用变址寄存器获得,寄存器要用中括号括起。
组合基址寄存器、位移量或比例,构成多种变址寻址方式:
mov eax,[ebx+esi] ;基址变址寻址
mov eax,[ebx+edi+80h] ;相对基址变址寻址
mov eax,[esi*2] ;带比例的变址寻址
mov eax,[edi*2+80h] ;带比例的相对变址寻址
mov eax,[ebx+esi*8+count] ;带比例的相对基址变址寻址
-
基址变址寻址
在变址寄存器不带比例(或者认为比例为1) 的情况下,需要配合使用一个基址寄存器。mov eax,[ebx+esi] mov eax,[ebx][esi] mov eax,[ebx+edi] mov eax,[ebx][edi]
-
相对基址变址寻址
由基址寄存器、变址寄存器与位移量相加构成有效地址(便于支持两维数组等数据结构)mov eax,[ebx+edx+80h] mov eax,80h[ebx+edx] mov eax,80h[ebx][edx]
-
带比例的变址寻址
变址寄存器内容乘以比例1、2、4或8的变址寻址(比例1、2、4和8对应8、16、32和64位数据的字节个数,便于以数组元素为单位寻址相应数据)mov eax,[ebx*4] ;带比例的变址寻址 mov eax,[esi*2+80h] ;带比例的相对变址寻址 mov eax,[ebx+esi*4] ;带比例的基址变址寻址 mov eax,[ebx+esi*8-80h] ;带比例的相对基址变址寻址