【汇编语言】8086汇编,快速搞定各种寻址方式:立即数寻址 / 寄存器寻址 / 存储器寻址

0 前言

众所周知,对于8086汇编语言,有几大寻址方式,不过我觉得这个好墨迹,会用就可以了,为什么命名这么多,这次只说本质,不说命名,至于命名,还是得知道,毕竟是大部分人公认的,不能反抗这点哦,但是你知道,不代表你真的要这么去想。

1 何为寻址?何为寻址方式?

看了很多资料,让人眼花缭乱,各种专业词汇让人眼花缭乱,扑朔迷离,我直接用最简练的语言说明。

  • 寻址,就是找数据
  • 寻址方式,就是找数据的方法

接下来,根据数据的位置,我再细说一下各种寻址方式。

2 立即数寻址

一句话,在指令中找数据

访问方式: 找指令的时候,顺便将数据带过来了,怎么找指令就怎么找它。

举例:

mov ax,1000h

1000h就是立即数,也就用到了立即数寻址

3 寄存器寻址

一句话,在寄存器中找数据

访问方式: 直接写上寄存器的名字,就能访问了。

举例:

mov ax,1000h

ax就是寄存器的名称,也就用到了寄存器寻址

4 存储器寻址

一句话,在存储器中找数据。(这里的存储器,通常情况下指的是主内存)

访问方式: 表示出存储单元的地址,就能访问了。

唯独存储器寻址比较麻烦,因为它表示地址的方式有很多种

但是在我这里,也就一句话,地址的形成方式是:BX,BP,SI,DI和立即数的各种组合

其实也就这些而已,只不过还有一些其他的规则限定,我也来细说一下(顺便说一句,这些东西,先看懂理解,然后自己动手试一下,多试试就学会了,不要背)。

BX —— based register——基地址寄存器
BP —— base point——基础指针
SI —— source index——源变址寄存器
DI —— destination index——目的变址寄存器

先给出你英文全称,你就很快能够知道,为什么是这几个寄存器了。

4.1 语法格式

mov ax,dataSegmentName
mov ds,ax
mov 目标,[address]

使用存储器寻址的时候,需要

  1. 设置好DS的值
  2. 再设置[address]的值,address的内容,就是上面说的

4.2 各种存储单元地址的生成方式

这里,我结合大家公认的命名,以及我自己的观点,阐述这些内容。

不管是什么寻址方式,本质就是为了生成address的值,生成数值的本质,就是我说的5个东西(bx,bp,si,di,立即数)进行基本的数学运算

  1. 寄存器直接寻址
    由立即数提供偏移地址。
mov ax,ds:[1000h]

在汇编语言中,立即数作为偏移地址,前面需要显式地加上提供段地址的寄存器,另外,这种显式的方式,一样可以应用于后面的方式,但是不是强制的。

  1. 寄存器间接寻址
    bx,si,di提供偏移地址,注意没有BP,至于原因,与硬件设计和语法设定有关,不必追究。
mov ax,[bx] ; 也可以写上 mov ax,ds:[bx]
mov ax,[si]
mov ax,[di]

另外,也可以使用其他段寄存器(ss,cs,es)提供段地址,显示加上就可以,mov ax,ss:[bx],这样就由ss提供段地址,bx提供偏移地址。

  1. 基址寻址
    bx + 位移量bp + 位移量提供偏移地址。

特殊:只有bp提供偏移地址的时候,默认ss寄存器提供段地址,其他的默认ds。

mov ax,[bx + 10H] ; 本质 mov ax,ds:[bx + 10H]
mov ax,[bp + 10H ]; 本质 mov ax,ss:[bp + 10H]

另外,在寻址范围之内,位移量可正可负可为0,下面的4,5也是这样。

  1. 变址寻址
    si + 位移量di + 位移量提供偏移地址。
mov ax,[si - 10h]
mov ax,[di - 10h]
  1. 基址变址寻址
    1个基址寄存器 + 1个变址寄存器 + 位移量提供偏移地址,只有含有BP,就是SS提供段地址。
mov ax,[bx + si + 10h]

4.3 位移量为什么还可以是负数?

首先,你需要了解的是,这里的负数是十进制的负数,编码方式是二进制补码

位移量是正数,就代表在基础之上,加了东西
位移量是负数,就代表在基础之上,减了东西

说白了就是,可加可减,反正都是找数据,怎么找都可以,画个图你就明白了。

【汇编语言】8086汇编,快速搞定各种寻址方式:立即数寻址 / 寄存器寻址 / 存储器寻址_第1张图片

你可能问,如果是bx - 11h,但是bx < 11h,不是成了负数?注意,在二进制世界,减过头了,叫溢出,是正溢出,溢出的结果,就是循环回去。 我再画个图:
【汇编语言】8086汇编,快速搞定各种寻址方式:立即数寻址 / 寄存器寻址 / 存储器寻址_第2张图片
对于有符号数

正溢出:两数运算,大于最大的正数,进入负数区域
负溢出:两数运算,小于最小的负数,进入正数区域

4.4 小结

注意,位移量其实就是个常数,也可以说成立即数,大多数情况不用区分。

1个:[常数][bx][si][di]
2个:[bx + 位移量][bp + 位移量][si + 位移量][di + 位移量]
3个:[(bx或bp)+ (si或di)+ 位移量],注意,不可以是[bx + bp + 位移量][si + di + 位移量]

4.5 思想方法

需要注意的是,以上是数学运算,都是加减法,但是这只是在8086中,未来,还会有乘法的出现,但是依然没有脱离本质,address = { {BX,BP,SI,DI和立即数} 的基本数学混合运算}

希望你明白,之所以不要你去专注于各种被限定的寻址方式,是因为那些不是本质,掌握本质,把握知识源头,才能够更好地应对未来。

在x86-32汇编语言中,地址的生成方式,又有所改变。
例如:mov dword ptr [ebp+eax*4-6Ch],edx,如果你记忆的是8086汇编于寻址方式,那么这个新的方式,你依然要去记忆,但是如果你掌握的是本质,你就知道,这不过是在生成地址的过程中,增加了一个乘号而已,之后你再去探索一下,为什么增加这个乘号,你就可以快速透彻理解和掌握它了。

5 注意事项

需要注意的是,这些理解,是为了让你抓住本质,但是并不代表,你只知道这些就可以了,内些杂乱的命名,依然有存在的价值,你同样需要掌握。

最后,还有一个重要的感悟,那就是任何操作数,都需要应用到这些寻址方式,因为计算机的本质就是处理数据,数据又需要通过寻址来找到

推荐阅读:计算机处理信息的本质,是二进制数的运算(本文第2节)

你可能感兴趣的:(汇编语言)