关于asm:汇编语言中的寻址方式

47次阅读

共计 3030 个字符,预计需要花费 8 分钟才能阅读完成。

计算机的一条指令通常蕴含两局部:

其中,操作码规定了指令应实现的具体操作,在汇编语言中操作码用助记符示意,例如加法 ADD、传送 MOV,等等。操作数示意指令的操作对象,比方一条加法指令,操作数局部就要给出加数和被加数,它们可能寄存在不同的中央,或者在某一寄存器中,或者在存储器的某一存储单元中,指令要通过某种办法示意操作数是哪一种,操作数具体在哪里。

指令中提供操作数或操作数地址的办法叫寻址形式。8086/8088 CPU 各种指令中所需的操作数次要有 3 类:寄存器操作数(操作数在 CPU 的通用寄存器中),存储器操作数(操作数在内存的存储单元中),立刻数操作数(操作数是指令中给出的常数)。还有一类是输出 / 输入端口操作数(操作数在输出 / 输入的接口寄存器中),仅用在 IN 和 OUT 指令中。

上面按操作数的类型介绍 8086/8088 CPU 的寻址形式。

一、隐含寻址

有的指令中没有明确的操作数字段,操作的对象隐含在指令代码中,这种指令的寻址形式称为隐含寻址或叫固定寻址。例如:

DAA

这是一条十进制加法调整指令,尽管无操作数字段,但隐含规定是对寄存器 AL 的内容进行操作。

二、立刻寻址

如果操作数是一个常数,就毋庸寻找,这个常数就蕴含在指令代码中,立刻能够失去这个操作数,因而把这种模式叫立刻寻址。把一个常数操作数叫立刻数,也是这个起因。

三、寄存器寻址

如果指令要操作的数据在 CPU 外部的寄存器中,指令就能够间接书写这个寄存器名字示意这个操作数,利用这种提供操作数的办法叫寄存器寻址。例如:

MOV AX,BX

这是一条传送指令,把寄存器 BX 中的内容传送至寄存器 AX。如果 BX=4258H,那么指令执行后 AX=4258H,而 BX 的值放弃不变。

又如:“ADD AX,1234H”是将 AX 的数与常数 1234H 相加,对于指标操作数(第一个操作数)是寄存器寻址,源操作数(第二个操作数)则为立刻寻址。

四、存储器操作数的寻址形式

存储器操作数的寻址是一个如何在指令中给出该操作数在内存中寄存的存储单元地址问题。在程序中,一个存储单元的地址是采纳逻辑地址模式示意的,即:

段基值:偏移量

其中,段基值在某个段寄存器中。不同操作类别的指令主动对应不同的段寄存器,这是隐含约定的。如不想扭转这些约定,就毋庸在指令中给出段值。偏移量(又叫偏移地址或偏移值)示意了该存储单元与段起始地址之间的间隔(字节数),它须要在指令中通过某种模式的表达式给出,在对源程序进行汇编时,由汇编程序计算出表达式的值,这个由汇编程序计算出的操作数的偏移量叫作无效地址,用 EA 示意。

指令中给出存储器操作数地址的办法有两种。一种办法是间接给出操作数的偏移地址,这种办法叫间接寻址。这是最间接、简略的办法,但不便于拜访成组的数据。另一种办法是将操作数的偏移量放入某个寄存器中,将其作为地址指针,这种办法叫寄存器间接寻址。若地址指针的内容在程序运行期间进行批改,就能使得用该寻址形式的同一指令,能够对不同存储单元进行操作。上面具体讲述这些寻址形式。

(一)间接寻址

这种寻址形式是在指令中间接给出存储器操作数的偏移地址。无效地址 EA 可间接由偏移地址失去。这种寻址形式次要用于存取简略变量。

在间接寻址形式的指令中的偏移量能够用常数或变量名示意。

(1)用常数示意。例如:

MOV AX,DS:[100H]

该指令是把以后数据段偏移 100H 的字存储单元内容送至 AX。用常数示意时,段寄存器必须指明,不能缺省。

(2)用变量名示意。例如:

MOV  BX,VAR
MOV  AH,DA+2

第一条指令是把由变量名 VAR 所指的存储单元内容传送给 BX。第二条指令是把由变量名 DA 代表的地址偏移再加 2 的那个字节单元内容送给 AH。假如 VAR 的偏移量为 1000H,DA 的偏移量为 2000H,则上述两条指令等效为:

MOV  BX,DS:[1000H]
MOV  AH,DS:[2002H]

(二)寄存器间接寻址

寄存器间接寻址示意的偏移地址是由三个地址重量的某种组合模式给出,这三个地址重量如下。

(1)基址:由基址寄存器 BX 或基址指针 BP 提供的偏移地址。

(2)变址:由源变址寄存器 SI 或目标变址寄存器 DI 提供的偏移地址。

(3)位移量:是一个八位或十六位常数。有时在程序中以变量名或标号模式呈现,待汇编后换算成它们的偏移值。

三个地址重量的不同组合造成以下几种寻址模式。

1. 基址寻址

基址寻址应用基址寄存器 BX 或 BP 做间址寄存器,有 3 种等价的格局,如表 1 所示。这种寻址形式是将基址寄存器 BX 或 BP 的内容与位移量(如果有的话)之和作为操作数的无效地址。

表 1 基址寻址格局

例如:

MOV AH, [BX+VAR]

这条指令的性能是将寄存在内存数据段的某个存储单元中的字节数据传送到 AH 中,这个存储单元在数据段中的偏移地址由 BX 的内容和符号 VAR 代表的偏移量相加确定。

2. 变址寻址

变址寻址应用变址寄存器 SI 或 DI 做间址寄存器,其格局与基址寻址雷同。

例如:

MOV  AX,ARRY[SI]
MOV  [DI],BX
MOV  DX,[SI+Z]

3. 基址变址寻址

基址变址寻址应用一个基址寄存器和一个变址寄存器组合来实现的。有两种模式,如表 2 所示。


表 2 基址变址寻址的格局

留神以下两点。

(1)可能作为间址寄存器的只能是 BX、BP、SI、DI,其余任何寄存器都不具备间址性能。

(2)用 BX、SI、DI 做间址寄存器寻找操作数时,隐含规定段基值由 DS 提供。当用 BP 做间址寄存器来寻找操作数时,隐含规定段基值由 SS 提供。这一点务必留神。

例如,假如 BX 和 BP 中的内容都是 1000H,指令“MOV AX,[BX]”是将数据段中偏移地址为 1000H 的存储单元内容传送给 AX,而指令“MOV AX,[BP]”是将堆栈中 1000H 存储单元的内容传送给 AX。传送的数据可能在齐全不同的两处。

五、段基值的隐含约定

由下面的叙述可知,用不同的寻址形式拜访存储器,段基址的起源是不同的。个别地,随着操作类型的不同,偏移地址的起源也是不一样的。表 3 给出了不同操作类型取得段基址和偏移地址的不同起源。取指令、堆栈操作和串操作的目标这 3 种操作,它们的段地址别离来自 CS、SS 和 ES,这种隐含约定是不允扭转(代替)的,其余的操作则容许扭转。因为有了段的隐含约定,就使得要对某个存储单元的数据进行存取时,在程序语句中只需给出偏移地址,机器会依据段的隐含约定,正确地找到这个操作数。


表 3 逻辑地址的隐含约定

六、隐含段的扭转

从表 3 中能够看到,有些操作能够扭转段的隐含约定而用其余段代替,这对于要寻址的操作数未处于以后隐含段时的状况是十分有用的。有 3 种办法能够扭转隐含段。

1. 段更换

程序将内存分段后的段基址放入段寄存器中。段寄存器的以后内容就是以后段,程序所波及的内存单元的偏移量就是绝对于以后隐含段的。能够通过更换段寄存器值的办法扭转以后段,使之指向操作数所处的段。

例如,程序要解决的数据在以后代码段,那么,将以后代码段寄存器 CS 的内容放入数据段寄存器 DS 中,这样,以后数据段就指向了以后代码段,存取以后数据段中的操作数就是存取以后代码段中的内容。可应用下述指令实现:

PUSH  DS
PUSH  CS
POP   DS

2. 用 ASSUME 伪指令从新指定以后段

当须要扭转拜访的段时,能够用 ASSUME 伪指令从新指定段与段寄存器的分割。这样,汇编程序在汇编时就能产生正确的寻址。

3. 段超过

段超过不是通过扭转以后段寄存器的内容而是在指令寻址形式前退出段超过前缀的办法操作非隐含段的数据。

例如:

原文:汇编语言中的寻址形式

(完)

正文完
 0