汇编语言第三章小结

Posted gares

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了汇编语言第三章小结相关的知识,希望对你有一定的参考价值。

第三章 内存访问

字数据在内存中的存储

1.      内存以字节为单位,划分为若干个单元

2.      字数据的存-取原则:高-高  低-低(小端法)

即:

① 字数据的低位字节存放在低地址内存单元

    字数据的高位字节存放在高地址内存单元

② 取低地址内存单元地址作为字数据地址

例1:

字数据124EH的地址是( 1 )

字数据3020H存入内存后地址为4,则4存放( 30H ),3存放( 20H )

 

例2:

从地址单元1取出一个

(1)     字节数据为:  4EH

(2)     字数据为:124EH

(3)     双字数据为:2000124EH

 技术分享图片

 

 

数据在内存和CPU之间的传送

1.      要在CPU和内存单元之间传送数据,就必须知道内存单元的地址。

2.      执行指令时,默认情况下,8086自动取寄存器DS中的值为内存单元的段地址。

3.      用mov指令从10000H中读取数据

          1)10000H用段地址和偏移地址表示为1000:0

          2)将1000H放入ds,然后用 mov al,[0]

               […]表示一个内存单元,[…]中的数字表示内存单元的偏移地址,段地址默认放在ds内执行时自动取出

4.      DS寄存器(数据段段寄存器,用于存放数据段的「段地址」)

  说明:

  (1)     将一段内存用作数据段,是编程时的一种安排

  (2)     在mov, add, sub等汇编指令中,访问内存单元时,默认情况下,指的是数据段。

          mov  ax, [1]    ;ax? ((ds)) x 16 + 1)

 

 

 

汇编指令mov, add, sub

1.      mov形式

 技术分享图片

注意:

1) 两个操作数长度要一致

2) 关于常数(也叫立即数)

① 不能作为第1个操作数(目的操作数)

② 作第2个操作数(源操作数)时,如果最高位是十六进制的a~f或A~F,前面要加零

3) 两个内存单元之间不能直接传送数据

4) 不能使用mov指令修改CSIP的值

5) 关于段寄存器

① 两个段寄存器之间不能直接传送;

② 不能把常数送到段寄存器。

 

错误举例:

1) mov ax,cl

2) ,mov al 300

3) mov 4000H,ax

4) mov ax A400H

5) mov [1],[2]

6) mov ds,cs

7) mov ds,1000H

 

 

2.      add形式

 技术分享图片

 

注意:

1) 操作数是内存单元时,指令中只给出「偏移地址」

2) 默认,「段地址」在ds中

3) add指令的操作数不能同时是内存单元

4) add指令的操作数不能是段寄存器

 

错误举例

1) add [1],[2]

2) add ds,[2]

 

 

3.      sub形式

 技术分享图片

 

注意:

1) 操作数是内存单元时,指令中只给出「偏移地址」

2) 默认,「段地址」在ds中

3) 两个内存单元不能直接使用sub指令相减

4) sub指令的操作数不能是段寄存器

 

错误举例:

1)sub [1],[2]

 

mov,add,sub举例

例1:写指令,计算从123B0H单元开始的前3个字节数据的累加和

              mov ax, 123BH

mov ds, ax

mov al, 0

add al, [0]

add al, [1]

add al, [2]

 

例2:写指令,计算从123B0H单元开始的前3个字数据的累加和

              mov ax, 123BH

mov ds, ax

mov ax, 0

add ax, [0]

add ax, [2]

add ax, [4]    

 

例3:写指令,交换从123B0H单元开始的两个字节数据

              mov ax, 123BH

mov ds, ax

mov al, [0]

mov bl, [1]

mov [1], al

mov [0], bl

 

 

1.      栈是一个逻辑上的概念,可以将一段内存空间当作「栈」来使用

2.      栈的特性:后进先出

3.      8086中栈以字为存取单位

4.      栈顶: 最后入栈的字数据所对应的地址单元

5.      栈底: 固定的一端,栈区最高地址单元的前一个单元

6.      入栈: 把数据存入栈

    第1步: 栈顶上移两个单元,即: 栈顶-2 → 栈顶

    第2步: 存入数据

7.      出栈: 从栈取出数据

    第1步: 取出字数据 → AX

    第2步: 栈顶下移两个单元,即: 栈顶+2 → 栈顶

8.      从栈中取出一个字数据给BX

    第1步: 取出数据→ BX

    第2步: 栈顶下移两个单元,即: 栈顶+2→栈顶

9.      栈为空时,栈顶指向栈底+2

 

 

与「栈」相关的寄存器SS和SP

1.      SS: 栈段段寄存器,用于存放栈段「段地址」

2.      SP: 栈指针寄存器,用于存放栈顶偏移地址

3.      SS:SP对应的物理地址栈顶的物理地址

    (SS) × 16 + (SP)  → 栈顶的物理地址

 

例子:设将20000H~2FFFFH这段内存当作栈来使用,栈的当前状态如图所示。

分析连续两次出栈操作SS和SP的内容的变化

技术分享图片

初始:

(SS) = 2000H

(SP) = FFFCH

第1次出栈:

(SS) = 2000H

(SP) = FFFEH

第2次出栈:

(SS) = 2000H

(SP) = 0000H

 

 

 

「栈」操作指令: push和pop

 技术分享图片

 

注意:

1) 在 push 内存单元 和 pop内存单元 中,指令中只需给出「偏移地址」,默认段地址在DS中

2) 对8086CPU而言,push和pop的操作:

    入栈和出栈均以字为单元

    操作对象不能是常数

    pop 段寄存器中,段寄存器不能是CS和SS

3) 利用栈「后入先出」特性,使用push和pop指令可以完成一些特殊处理

4) 以下两种情形会发生「栈顶超界」问题

    1.当栈满的时候,再使用push指令入栈

    2.当栈空的时候,再使用pop指令出栈

    8086CPU不会自动考虑栈顶超界,需要程序员在编程设计时自己考虑。栈区长度不同,栈顶超界的具体情形也不同。

 

举例:

1.设将10000H~1FFFFH这段内存当作栈来使用

栈的初始状态如图所示。(SS) = 1000H  (SP) = 000EH

pop  ax        ; (ax) = 1234H

                     SP  ← (SP)  + 2

                     (SP) = 0010H

 

pop  ax        ; (ax) = ××H

                     SP  ← (SP)  + 2

                    (SP) = 0012H

 技术分享图片

 

2. 设将10000H~1000FH这段内存当作栈来使用

栈的初始状态如图所示。(SS) = 1000H  (SP) = FFFEH

 

pop  ax        ; (ax) = 1234H

                     SP  ← (SP)  + 2

                     (SP) = 0000H

 

pop  ax        ; (ax) = ××H

                     SP  ← (SP)  + 2

                    (SP) = 0002H

 技术分享图片

 

 

 

利用栈“保护现场”

设将10000H~1000FH这段内存当作栈来使用

栈的初始状态为空。(bx)=0010H, (cx)=2010H

mov   ax, 1000H

mov   ss, ax

mov   sp, 0010H

push bx

push cx

    …       ;修改bx,cx

pop cx

pop bx

代码段执行完后,bx和cx内容未变

 

 

利用栈实现数据交换

设将10000H~1000FH这段内存当作栈来使用

栈的初始状态为空。(bx)=0010H, (cx)=2010H

mov   ax, 1000H

mov   ss, ax

mov   sp, 0010H

push bx

push cx

    …       ;修改bx,cx

pop bx

pop cx

代码段执行完后,bx和cx内容交换

 

 

关于「段」的小结

(1)「段」是一个逻辑上的概念。

编程时,可根据需要指定一段内存区用作数据段、代码段或是栈段。

(2) 用作数据段时,要把段地址→DS

   用作栈段时,要把段地址→SS,栈顶偏移地址 → SP

用作代码段时,段地址→CS,要取的指令偏移地址→IP。但CS和IP的值不能使用mov改变。

(3) 一段内存可以同时用作代码段、数据段、栈段。

     由编程时灵活确定。

(4) 在8086CPU中,每个段的最大长度不能超过64KB。

(因为寄存器是16位的,能表示的地址范围只能是0000H~FFFFH,即0~216-1)

 

以上是关于汇编语言第三章小结的主要内容,如果未能解决你的问题,请参考以下文章

汇编语言第1章 基础知识

汇编语言第2章 寄存器

汇编语言第3章 寄存器(内存访问)

python学习第三天

Python自然语言处理工具小结

汇编小结(第一章)