汇编语言程序设计

第3章 寄存器(内存访问)

3.1 内存中的字存储
内存以字节为单元,划分为若干个单元。1字节=8比特
在Intel术语规范中:

  • 字:16位数据(2字节)
  • 双字:32位数据(4字节)
  • 四字:64位数据(8字节)

字数据占用两个连续字节,取低地址作为字数据地址。
小端法:从最小的地址开始,先放位字节数据
大端法:从最小的地址开始,先放位字节数据
例如:向0号单元写入2049H

8086 CPU 采用小端法存放数据,即高地址内存单元存放字型数据的高位字节,低地址内存单元存放字型数据的低位字节。

3.2 DS 和 [address]
CPU要读写一个内存单元的时候,必须先给出这个内存单元的地址,在 8086PC 中,内存地址由段地址和偏移地址组成。8086中有一个DS寄存器,通常用来存放要访问数据段的段地址。
DS(Data segment):数据段段寄存器,用于存放数据段的段地址。
在 mov、add、sub等汇编指令中,访问内存单元时,默认情况下,指的是数据段。
[address] 中address表示偏移地址,
例如:
mov ax, [201] ; ax <— (( ds ) × 16 + 201 )
在这里插入图片描述
3.3 字的传送

只要在 mov 指令中给出16位寄存器就可以进行16位数据的传送了,即字数据。

3.4 mov 、add、sub 指令
在这里插入图片描述
在这里插入图片描述
注意事项

  • 两个操作数长度要一致
  • 关于常数/立即数
    1.不能作为目的操作数
    2.作为源操作数时,如果最高位是十六进制的a~f 或A ~ F,前面要加0
  • 两个内存单元之间不能直接传送数据
  • 不能用mov 指令修改CS和IP值
  • 关于段寄存器
    1.两个段寄存器之间不能直接传送
    2.不能把常数送到段寄存器

在这里插入图片描述
注意事项

  • add指令的操作数不能同时是内存单元
  • add指令的操作数不能是段寄存器

在这里插入图片描述

  • 两个内存单元不能直接使用sub指令相减
  • sub指令的操作数不能是段寄存器

3.5 数据段
对于 8086PC 机,可将一组内存单元定义为一个段,将一组长度为N(N<=64)、地址连续、起始地址为16的倍数的内存单元当作专门存储数据的内存空间,从而定义了一个数据段。
写几条指令,累加数据段中的前3个字型数据。

mov ax, 123BH
mov ds, ax
mov ax, 0
add ax, [0]
add ax, [2]
add ax, [4]

3.6 栈

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

栈的特性:后进先出
两个概念:栈底、栈顶
两个操作:入栈、出栈
一个约定:8086中栈以为存取单元

栈顶:最后入栈的字数据所对应的地址单元
栈底:固定的一端,栈区最高地址单元的前一个单元
入栈:把数据存入栈
出栈:从栈取出数据
在这里插入图片描述
入栈操作分析(push):
①栈顶上移两个单元,即 SP <—— SP-2
②存入数据

出栈操作分析(pop):
①取出字数据
②栈顶下移两个单元,即 SP <——SP+2

说明:栈为空的时候,栈顶指向栈底+2


与栈相关的寄存器SS和SP
SS:栈段段寄存器,用于存放栈段的段地址
SP:栈指针寄存器,用于存放栈顶的偏移地址
SS:SP对应的物理地址是栈顶的物理地址

任意时刻,SS:SP指向栈顶元素。
8086CPU 只记录栈顶,栈空间的大小我们自己管理。
push、pop指令实质上是一种内存传送指令。

在这里插入图片描述
注意事项

  • 操作对象不能是常数
  • pop 段寄存器 指令中,段寄存器不能是CS和SS
  • 栈顶越界
    当栈满的时候,再使用push指令入栈;
    当栈空的时候,再使用pop指令出栈;

栈应用举例:

  • 利用栈“保存现场”
  • 利用栈实现数据交换
    在这里插入图片描述
    在这里插入图片描述

段是一个逻辑上的概念。编程时,可根据需要指定一段内存空间用作数据段、代码段或是栈段。

  • 用作数据段时,要把段地址→DS
  • 用作栈段时,要把段地址→SS,栈顶偏移地址 → SP
  • 用作代码段时,要把段地址→CS,要取的指令偏移地址→IP。但CS和IP的值不能使用 mov 改变。

检测点3.1
(1)在Debug中,用“d 0:01f” 查看内存,结果如下

0000:0000  70  80  F0  30  EF  60  30  E2-00  80  80  12  66  20  22 60
0000:0010  62  26  E6  D6  CC  2E  3C  3B-AB  BA  00  00  26  06  66 88

AX=0,BX=0,写出每条汇编指令执行完后相关寄存器中的值

mov ax,1
mov ds,ax
mov ax,[0000]			;AX=2662H
mov bx,[0001]			;BX=E626H
mov ax,bx               ;AX=E626H
mov ax,[0000]           ;AX=2662H
mov bx,[0002]		    ;BX=D6E6H
add ax,bx				;AX=FD48H
add ax,[0004]			;AX=2C14H
mov ax,0				;AX=0000H	
mov al,[0002]			;AX=00E6H
mov bx,0				;BX=0000H
mov bl,[000C]			;BX=0026H
add al,bl				;AX=000CH

可以使用debug编写指令进行验证
在这里插入图片描述
部分追踪截图
-e 向内存写入数据
-a 编写汇编指令
-t 单步追踪
(2) 内存中的情况如图所示
在这里插入图片描述
各寄存器的初始值:cs=2000h,ip=0,ds=1000h,ax=0,bx=0;
①写出CPU执行的指令序列。
②写出CPU执行每条指令后,CS、IP和相关寄存器中的数值。
③再次体会:数据和程序有区别吗?如何确定内存中的信息哪些是数据,哪些是程序?


mov ax,6622
jmp 0ff0:0100
mov ax,2000
mov ds,ax
mov ax,[0008]
mov ax,[0002]

寄存器\指令123456
CS200010001000100010001000
IP00030000000300050008000B
AX6622662220002000C389EA66
BX000000000000000000000000
DS100010001000200020002000

③数据和程序在计算机中都是以二进制的形式存放的,在区别程序和数据时,关键是看段地址,如果段地址是ds段,说明内存中存放的是数据,如果段地址是cs段,说明该内存中存放的是程序指令。

检测点3.2
补全代码,使其可以将10000H~1000FH中的8个字,逆序复制到20000H ~2000FH中。
(1)

mov ax,1000H
mov ds,ax
mov ax,2000H
mov ss,ax
mov sp,0010H
push [0]
push [2]
push [4]
push [6]
push [8]
push [A]
push [C]
push [E]

(2)

mov ax,2000H
mov ds,ax
mov ax,1000H
mov ss,ax
mov sp,0000H
pop [E]
pop [C]
pop [A]
pop [8]
pop [6]
pop [4]
pop [2]
pop [0]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值