快捷搜索: 王者荣耀 脱发

【x86汇编】第二章:寻址方式

寻址方式

定义:寻找操作数存放地址的方式 在进行一个操作之前,需要知道源操作数和目的操作数分别存放在什么位置,用什么方式去找到这个位置

操作数的位置

    CPU寄存器 主存(内存) IO设备

寄存器寻址

示例:INC AX

操作数存放在CPU寄存器内,寄存器的名字就是它的地址,直接操作对应的寄存器

    操作数的类型:由所用寄存器的位数决定,如AX是16位字类型

寄存器间接寻址

示例:MOV AX, [SI]

操作数存放在内存中,需要通过寄存器的值(该值就是操作数的偏移地址EA)间接找到操作数

    操作数的类型:不明确,对于双操作数的指令,如例子所示,由于AX类型已知,则另一个操作数默认使用同样类型,如果两个操作数类型都不明确,则出错 寄存器的选择: 可以是32位的8个通用寄存器 也可以是4个16位通用寄存器(BX,DI,SI,BP) 但是不能是8位寄存器,需要注意的是被允许的16位寄存器只有这四个 操作数的段:如果寄存器选用ESP、SP、BP,则默认在堆栈段SS,否则一律默认在数据段DS

变址寻址

示例:MOV AL, 5[EBX]

操作数存放在内存中,需要根据寄存器的值、比例因子、位移量,计算出操作数的偏移地址EA,然后去所在段找到操作数,注意选用ESP时,比例因子F只能为1

    书写形式:常见以下三种,其中R是寄存器,F是比例因子,V是位移量 1.[R * F + V] 2.[R * F] + V 3.V [R * F] 寄存器选择,操作数的段,同间接寻址的规定一样

基址加变址寻址

示例:MOV AX, 8[BX][SI]

操作数在内存中,先计算EA,再在段中找到操作数

    书写格式:常见的以下三种,BR是基址寄存器,IR是变址寄存器,F是比例因子,V是位移量 1.[BR + IR * F + V] 2.V [BR] [IR * F] 3.V [BR + IR * F 寄存器选择: 16位寄存器,BR只能选择BP、BX,IR只能选择DI、SI,F只能为1 32位寄存器,BR可选择任意通用寄存器,IR可选择除ESP外的任意通用寄存器 操作数的段: 选择EBX/BX时,段寄存器默认DS 选择EBP/BP时,段寄存器默认SS

立即寻址

示例:ADD EAX, -1

操作数是一个有符号数,且只能是源操作数(IO寄存器除外)

直接寻址

示例:MOV DS:[20H], CL

操作数在内存中,指明操作数的段(部分情况下可省略),后面紧跟偏移地址EA,EA是一个无符号数 需要注意,操作数类型一定要明确

寻址相关的问题

显示/隐含操作数

一些指令显示的指明操作数,有些则相反

各寻址方式的关系

根据操作数存放的位置,寻址方式分为三类:

    寄存器方式:寄存器寻址 存储器方式:寄存器间接寻址,变址寻址,基址加变址寻址,直接寻址 立即方式:立即寻址

源操作数和目的操作数的存放位置

    对于双操作数的指令,源操作数和目的操作数不能同时使用存储器方式,也就是说不能都来自于内存 立即寻址的操作数,只能是源操作数

寄存器方式寻址的操作数,其数据类型是不明确的,必要情况下,需要额外声明

    BYTE PTR WORD PTR DWORD PTR

段选择说明

    如果不希望使用默认段寄存器,也可以显式地指定,也就是在对应的寻址方式表达式之前,加上段超越前缀(跨段前缀) 段超越前缀可以使用任意段寄存器 不受跨段前缀影响的情况 取指令时,只能是CS段 压栈和出栈,只能是SS段 串操作中,目的串只能是ES段
经验分享 程序员 微信小程序 职场和发展