汇编语言之寻址方式(超详细~)
1 固定寻址(inherent addressing )
特定的单操作数指令,操作数隐含在操作码中,在固定寻址的指令中,操作数被隐含在指令中,不需要执行总线周期,执行速度快
例子:
CBW命令,将AL中的符号位扩展到AH中,形成16位的操作数。比如AL中的符号位是1,则执行CBW命令后,AH则变成FF,如果符号位是0,则AH则变成00
PUSH AX ,源操作数是寄存器AX,目的操作数为堆栈顶部,将AX寄存器中的内容压入堆栈
CWDE命令,是32位汇编指令,将AX中的符号位扩展到EAX的高位。
2 立即数寻址 (immediate addressing)
立即数寻址中,操作数包含在指令中,作为指令的一部分。特点:执行速度快,主要给寄存器赋值。同样不需要执行总线周期。
例子:
mov ax,14 ;主要给寄存器赋值,不能直接给段寄存器赋值,如不能mov ds/es/ss/cs ,立即数,会报错
3 寄存器寻址(register addressing)
说白了,就是操作数在寄存器中,直接去寄存器中寻找操作数。
例子:
mov ax,bx ;两个操作数都是寄存器寻址,
mov [1234h],ax ; 将AX寄存器中的值给地址1234处,当然段地址在DS中,可以用debug做实验验证下,如下:
运行-debug -r 查看寄存器中的值 -a 编辑汇编命令 输入mov ax,12 mov [1234],ax, 然后查看1234处的指令 -d ds:1234 ;验证此时的值 然后运行两次 -p命令, 然后执行-d ds:1234命令,可以看到1234处的值变了
【文章福利】小编推荐自己的Linux内核技术交流群:【891587639】整理了一些个人觉得比较好的学习书籍、视频资料共享在群文件里面,有需要的可以自行添加哦!!!(含视频教程、电子书、实战项目及代码)


4 存储器寻址(momory addressing)
就是操作数存放在存储器中,用存储器寻址的指令,操作数一定在数据段、堆栈段、附加段中的主存储器中,指令中一定包含有存储器单元的地址或产生存储器单元地址的
信息,执行指令时,CPU先根据指令提供的地址信息,计算出偏移地址,用地址产生器产生出直接访问的内存地址,再从内存中取到操作数,执行规定的操作。
注意点:
可以采用段跨越前缀的方式来改变系统指定的默认段,(有的人叫段超越),默认的是DS段
串处理指令必须用ES段
栈操作指令必须用SS段
指令必须在CS中
储存器的地址是 段基地址偏移4位+偏移地址 ,由于偏移地址是16位的,所以2的16次方是64K,所以每个段的最大长度为64K 。存储器寻址方式如下:
4.1 直接寻址方式(direct addressing)
例子:
mov al,[2000] ;源操作数是直接寻址,目的操作数是寄存器存执,指令执行结果是将DS段中的偏移地址为2000的字节单元传送到AL中
mov ax,[2000] ; 唯一与上一条不同的是将字单元传送到AX中
mov ax ,es:[2000] ;段超越
mov dword ptr [1234] ,eax ;将EAX中的32位双字数据传送到内存中,目的操作数采用的存储器存执,源操作数采用寄存器存执。
4.2 寄存器间接寻址方式(register indirect addressing)
指操作数的偏移地址存放在制定的寄存器中,寄存器作为指针指向内存单元,而操作数在存储器中,这样的寄存器称为间址寄存器
在8086CPU中,只能使用BX,BP,SI ,DI 四个寄存器来充当存储器地址来进行寻址。BX,BP作为基址寄存器,SI,DI变址寄存器
当BX,SI,DI作为间址寄存器时,默认段寄存器在DS中,BP作为间址寄存器时,默认段寄存器为SS。
当然可以采用段超越改变段地址。
4.3 寄存器相对寻址方式(register relative addrssing)
与寄存器间接寻址方式类似,但不同的是,指令中还需要指定一个位移量,对于16位系统来说,位移量是8位或16位,对于32系统来说,位移量是
8位或32位的位移量,位移量是一个带符号的整数。
mov ax,10h[si] ;等值与mov ax,[si+10h]
4.4 基址变址寻址方式(based indexed addressing)
操作数的偏移地址一部分在基址寄存器,一部分在变址寄存器,基址寄存器的内容加上变址寄存器的内容就是操作数的偏移地址,
例子:
mov ax,[bx][si] 等价于mov ax,[bx+si]
4.5 相对基址变址寻址方式(relative based indexed addressing)
带位移量的基址变址寻址方式称为基址 变址寻址方式。
例子:
mov ax,100[bx][si] ;段地址再DS中 mov ax,100[bp][si] ; 段地址再SS中
4.6 比例变址寻址方式(scaled indexed addressing)
只有在32位及以后的80X86系统中使用,暂不介绍
5 I/O地址寻址(
分为直接端口寻址和间接端口寻址
5.1 direct i/o port addressing
用00h-ffh表示最低的0-255个8位的I/O端口地址,就可以直接进行I/O端口寻址,则可以寻址256个。
in al,80h;将80h端口的数据输入到AL寄存器中
in ax,80h;将80H端口的数据输入到AX寄存器中。
out 80h,AL;字节输出指令,将AL寄存器的内容输入到80H端口
5.2 indirect i/o port addressing
如果端口大于256个,则可以寻址65536个端口,必须使用间接寻址,先把0000H-FFFFH端口号存放到DX中,然后将DX寄存器中的值
mov ax,200h
out dx,al ; jiang AL输出到DX所指向的端口中
mov dx ,200h
in ax ,dx;将dx所指向的端口的一个字输入到AX寄存器中。
与转移地址有关的寻址
此类主要说的是转移指令,转移指令可以改变指令的执行顺序,进行跳转,简言之,就是改变CS和IP的值,从而改变下一条要执行的指令的物理地址
转移分为段内转移和段间转移,段内转移只是改变IP,并不改变CS,段间转移都改变。
段内转移和段间转移,都可以使用直接寻址和间接寻址
6.1 段内直接寻址 (intra segment indirect addressing)
jmp label ;label 为转移的地址符号,也称标号,
具体例子如下:
jmp short s add ax,1 s:inc ax 当执行到jmp short s 后,会跳转到inc ax 执行。
6.2 段内间接寻址(intra segment indirect addressing)
转移的偏移地址是一个寄存器或时一个存储单元的内容,举例:
jmp bx ;BX内容传送到IP寄存器中,作为段内偏移地址 jmp word ptr [bp] ;BP指向的内存单元的一个字传送到IP,作为偏移地址 jmp word ptr[bp +val] ;BP+VAL指向的内存单元的一个字送给IP,作为偏移地址
6.3 段间直接寻址(inter segment direct addressing)
段间寻址和段内直接寻址类似,指令中直接给出转移地址,与段内寻址不同的是,段内直接寻址时,指令中提供了转移地址的段地址和偏移地址 将其中的段地址传送给CS,偏移地址传给IP. 完成程序控制间的段间转移 例子:jmp far ptr nseg ;在符号地址nseg之前加上表示段内转移的操作符far ptr
6.4 段间间接寻址(inter segment indirect addressing)
间接的获取转移的段地址和偏移地址,目的地址的段地址和偏移地址存放在内存中,这里存储单元的地址是由指令制定存储器寻址方式获取的
指令的格式:
jmp dword ptr [si] ;寻址方式为存储器寻址方式, dword ptr 为双字操作符,说明转移地址需取双字为段间转移地址,其中高字是段地址。转入CS,低字转入IP. jmp dword ptr [addr] ;在32位系统中,使用存储器寻址方式获取内存单元的48位指针,其中的低32位送EIP寄存器,高16位从CS寄存器,就能取得转移地址
