(1)处理的数据在什么地方?
(2)要处理的数据有多长?
为了描述上的简洁,使用描述性的符号 reg 来表示一个寄存器,用sreg表示一个段寄存器。
reg 的集合包括: ax、 bx、cx、dx、ah、al、 bh、bl、ch、cl、dh、dl、sp、bp、si、di;
sreg的集合包括: ds、ss、cs、es。
8.1 bx、si、di和 bp
(1)在8086CPU中,只有这4个寄存器可以用在“[…]”中来进行内存单元的寻址。比如下面的指令都是正确的:
而下面的指令是错误的:
(2)在[…]中,这4个寄存器可以单个出现,或只能以4种组合出现: bx和 si、bx和di、 bp和 si、bp和 di。比如下面的指令是正确的:
下面的指令是错误的:
(3)只要在[…]中使用寄存器 bp,而指令中没有显性地给出段地址,段地址就默认在ss 中。比如下面的指令。
8.2 机器指令处理的数据在什么地方
绝大部分机器指令都是进行数据处理的指令,处理大致可分为3类:读取、写入、运算。在机器指令这一层来讲,并不关心数据的值是多少,而关心==指令执行前一刻==,它将要处理的数据所在的位置。指令在执行前,所要处理的数据可以在3个地方:CPU内部、内存、端口(端口将在后面的课程中进行讨论),比如表8.1中所列的指令。
8.3 汇编语言中数据位置的表达
(1)立即数(idata)
对于直接包含在机器指令中的数据(执行前在CPU的指令缓冲器中),在汇编语言中称为:立即数(idata),在汇编指令中直接给出。
(2)寄存器
指令要处理的数据在寄存器中,在汇编指令中给出相应的寄存器名。
(3)段地址(SA)和偏移地址(EA)
指令要处理的数据在内存中,在汇编指令中可用[X]的格式给出 EA,SA在某个段寄存器中。
8.4 寻址方式
8.5 指令要处理的数据有多长
(1)通过寄存器名指明要处理的数据的尺寸。
例如,下面的指令中,寄存器指明了指令进行的是字操作。
下面的指令中,寄存器指明了指令进行的是字节操作。
(2)在没有寄存器名存在的情况下,用操作符X ptr指明内存单元的长度,X在汇编指令中可以为word或 byte。
例如,下面的指令中,用word ptr指明了指令访问的内存单元是一个字单元。
下面的指令中,用byte ptr指明了指令访问的内存单元是一个字节单元。
(3)其他方法
有些指令默认了访问的是字单元还是字节单元,比如,push [1000H]就不用指明访问的是字单元还是字节单元,因为==push指令只进行字操作==。
8.6 寻址方式的综合应用
C语言版本:
汇编语言版本:
一般来说,我们可以用[bx+idata+si]
的方式来访问结构体中的数据。用bx定位整个结构体,用idata定位结构体中的某一个数据项,用si定位数组项中的每个元素。为此,汇编语言提供了更为贴切的书写方式,如:[bx].idata
、[bx].idata[si]
。
8.7 div指令
(1)除数:有8位和16位两种,在一个reg 或内存单元中。
(2)被除数:默认放在AX或DX和AX中,如果除数为8位,被除数则为16位,默认在AX中存放;如果除数为16位,被除数则为32位,在DX和AX中存放,DX存放高16位,AX存放低16位。
(3)结果:如果除数为8位,则AL存储除法操作的商,AH存储除法操作的余数;如果除数为16位,则AX存储除法操作的商,DX存储除法操作的余数。
编程,利用除法指令计算100001/100。
编程,利用除法指令计算1001/100。
8.8 伪指令dd
前面我们用db和dw定义字节型数据和字型数据。dd是用来定义 dword(double word,双字)型数据的。
第一个数据为01H,在 data:0处,占1个字节;
第二个数据为0001H,在data:1处,占1个字;
第三个数据为00000001H,在 data:3处,占2个字。
8.9 dup
==实验 寻址方式在结构化数据访问中的应用==
P172