运行的程序保存于主存储器,需要通过存储器地址访问程序的指令和数据 通过地址访问指令或数据的方法称为寻址方式
(Addressing Mod) 一条指令执行后,确定下一条执行指令的方法是指令寻址
。执行过程中,访问所需要操作的数据(操作数)的方法是数据寻址
。
IA-32 处理器除外设数据外的数据寻址方式有以下三类:
? 用常量表达的具体数值(立即数寻址)
? 用寄存器名表示的其中内容(寄存器寻址)
? 用存储器地址代表的保存的数据(存储器寻址)
在立即数寻址(或立即寻址)方式中,指令需要的操作数紧跟在操作码之后作为指令机器代码的一部分,并随着处理器的取指操作从主存进入指令寄存器。
十六进制常数
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
代码段使用标号名代表其偏移地址
立即数的类型由对应的寄存器或变量类型决定。
字节变量bvar类型
0000001C C6 05 00000000 R 4C
mov bvar, 01001100b
双字变量dvar类型
00000023 C7 05 00000006 R 00000012
mov dvar+4, 12h
符号 | 含义 |
---|---|
i8 | 8位立即数 |
i16 | 16位立即数 |
i32 | 32位立即数 |
imm | 立即数 |
指令的操作数存放在处理器的寄存器中,就是寄存器寻址方式。
目的操作数是寄存器寻址
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
mov edi,si
错误的原因是两个操作数的类型不匹配,因为 EDI 32 位寄存器SI 16 位寄存器, MOE 指令不允许把 16 位寄存器的数据传送到 32 位寄存器
符号 | 含义 |
---|---|
r8 | 8位寄存器 |
r16 | 16位寄存器 |
r32 | 32位寄存器 |
reg | 通用寄存器 |
寻址主存中存储的操作数就称为存储器寻址方式,也称为主存寻址方式 编程时,存储器地址使用包含段选择器和偏移地址的逻辑地址。
段寄存器的默认和超越
绝大部分情况使用默认规定,无需表达:
?读取指令,一定是代码段CS
?堆栈操作,针对堆栈段SS
?读写数据,默认在数据段DS
问存储器的方式 | 默认 | 可超越 | 偏移地址 |
---|---|---|---|
取指令 | 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位有效地址的组成
基址寄存器+变址寄存器+位移量
有效地址只有位移量部分,直接包含在指令代码中,用变量名(或加中括号)表示偏移地址
?直接使用变量名表达:变量名
?变量名加或减一个常量:变量名+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] ;带比例的相对基址变址寻址
20210323第一家量产国产化蓝牙AOA高精度定位基站生态合能培训会上海站现场直播下...
项目背景 最近项目里有个webpack版本较老的项目,由于升级和换框架暂时不被leade...
详解Spring mvc ant path的使用方法 概要: 任何一个WEB都需要解决URL与请求处理...
Epoll 是个很老的知识点,是后端工程师的经典必修课。这种知识具备的特点就是研...
这里尊托云数小编参考了几篇文章特为大家整理下,用到的朋友多支持一下了。 进行...
戳蓝字“ CSDN云计算 ”关注我们哦 作者 | 刘丹 出品 | CSDN云计算IDCSDNcloud ...
堆 Heap Heap:可以迅速找到一堆数中的 最大 或者 最小 值的数据结构。 将根节点...
1.现在复习的感觉就是:马上要有一大波僵尸涌过来,但老子连向日葵都还没种! 2...
WebService端代码 复制代码 代码如下: /// summary /// 上传文件到远程服务器 //...
IViewLocationExpander API ExpandViewLocations Razor视图路径,视图引擎会搜索...