8086 汇编笔记(二):寄存器(内存访问)

一、内存中字的存储

字单元的概念:字单元,即存放一个字型数据(16 位)的内存单元,由两个地址连续的内存单元组成

由上一章学习可知:高地址内存单元中存放字型数据的高位字节,低地址内存单元中存放字型数据的低位字节

现在有以下几个问题

(1) 0 地址单元中存放的字节型数据是多少? 20H

(2) 0 地址字单元中存放的字型数据是多少? 4E20H

(3) 2 地址单元中存放的字节型数据是多少? 12H

(4) 2 地址字单元中存放的字型数据是多少? 0012H

(5) 1 地址字单元中存放的字型数据是多少? 4E12 H

注意: 1 地址字单元,即起始地址为 1 的字单元,它由 1 号单元和 2 号单元组成

二、DS 和 [address]

8086 CPU 中有一个 DS 寄存器,通常用来存放要访问数据的段地址。比如我们要读取 10000H 单元的内容,可以用如下的程序段进行:

mov bx,1000H
mov ds,bx
mov al,[0]

上面的 3 条指令将 10000H(1000:0) 中的数据读到 al 中

8086 CPU 自动取 ds 中的数据为内存单元的段地址"[...]"表示一个内存单元,"[...]"中的 0 表示内存单元的偏移地址

另一个案例,如果将 10000H 单元的内容送入 al 中呢

mov [0],al

三、字的传送

前面我们用 mov 指令在寄存器和内存之间进行字节型数据的传送(8 位)

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

四、数据段

比如,将 123B0H~123B9H 的内存单元定义为数据段。现在要累加这个数据段中的前3 个单元中的数据,代码如下:

mov ax,123BH
mov ds,ax
mov al,0
add al,[0]
add al,[1]
add al,[2]
..............................

答案解析:

五、栈

六、CPU 提供的栈机制

8086 CPU 提供入栈和出栈指令,最基本的两个是 PUSH(入栈) 和 POP(出栈)。

8086 CPU 的入栈和出栈操作都是以字为单位进行的

请看以下指令

mov ax,0123H
push ax
mov bx,2266H
push bx
mov cx,1122H
push cx
pop ax
pop bx
pop cX

指令执行过程如下

8086 CPU 中,有两个寄存器,段寄存器SS和寄存器SP,栈顶的段地址存放在 SS 中,偏移地址存放在 SP 中

任意时刻,SS:SP 指向栈顶元素

pop 指令执行过程

七、栈顶超界问题

8086 CPU 不保证我们对栈的操作不会超界

总结:我们在编程的时候要自己操心栈顶超界的问题,要根据可能用到的最大栈空间,来安排栈的大小,防止入栈的数据太多而导致的超界;执行出操作的时候也要注意,以防栈空的时候继续出栈而导致的超界。

八、push、pop 指令

push 寄存器
push 段寄存器
push 内存单元

pop 寄存器
pop 段寄存器
pop 内存单元

编程:

将 10000H~1000FH 这段空间当作栈,初始状态栈是空的,将 AX、BX、DS

中的数据入栈

mov ax,1000H    ;设置栈的段地址,SS=1000H,不能直接向段寄存器SS中送入数据,所以用 ax 中转
mov ss,ax
mov sp,0010H
push ax
push bx
push cx

编程:

将 10000H~1000FH 这段空间当作栈,初始状态栈是空的,设置 AX-001AH,BX-001BH:将 AX、BX 中的数据入栈,然后将 AX、BX 清零,从栈中恢复 AX、BX 原来的内容

mov ax,1000H
mov ss,ax
mov sp,0010H    ;初始化栈顶
mov ax,001AH
mov bx,001BH
push ax
push bx
mov ax,0
mov bx,0
pop bx
pop ax
mov ax,1000H
mov ss,ax
mov sp,0002H
mov ax,2266H
push ax

push ax 是入栈指令,它将在栈顶之上压入新的数据。一定要注意:它的执行过程是,先将记录栈顶偏移地址的 SP 寄存器中的内容减 2,使得 SS:SP 指向新的栈顶单元,然后再将寄存器中的数据送入 SS:SP 指向的新的栈顶单元

原因:因为 8086 处理器是从高地址到低地址增长栈

九、栈段

如果将 10000H~IFFFFH 这段空间当作栈段,初始状态是空的,此时,SS=1000H,SP=?

栈段基址和栈指针的初始值

  • 栈段寄存器(SS)确定栈段的基址。给定SS = 1000H,那么栈段基址为10000H。
  • 栈指针(SP)指示当前栈顶的偏移量。对于一个空栈,SP的初始值应指向栈段的末尾,以便第一次 PUSH 操作能够在栈的顶部进行。

栈指针初始值的计算

8086处理器的栈段从高地址向低地址增长。即:

  • 栈顶在栈段的高地址。
  • 栈底在栈段的低地址。

为了确保栈初始为空,我们需要将SP设置为指向栈段的最高地址的下一个字(word)。

栈段范围是从10000H到1FFFFH,总大小为FFFFH字节。栈段最高地址是1FFFFH,如果初始SP指向1FFFFH,那么第一个 PUSH 操作会将数据放在1FFFDH和1FFFEH(SP减2后)的位置。因此,我们设置SP为栈段的最大容量加1,即栈段结束地址的下一个位置。

具体步骤

  1. 计算栈段大小

    • 栈段基址 = 10000H
    • 栈段结束 = 1FFFFH
    • 栈段大小 = 1FFFFH - 10000H + 1 = FFFFH + 1 = 10000H
  2. 设置初始SP

    • 初始SP = 栈段大小 = 10000H

由于8086处理器中的栈操作将SP减2后再存储数据,这样设置SP可以保证在第一次PUSH操作时SP减2后刚好在1FFFEH和1FFFDH位置存储数据。

相关推荐
最 上 川1 小时前
西电-神经网络基础与应用-复习笔记
人工智能·笔记·神经网络
番茄灭世神1 小时前
Qt学习笔记第81到90讲
笔记·学习
云计算DevOps-韩老师1 小时前
【网络云SRE运维开发】2025第2周-每日【2025/01/10】小测-【第10章 ACL理论和实操考试】
网络·智能路由器·运维开发
HehuaTang2 小时前
conntrack iptables 安全组
网络
Zero_Era2 小时前
LKT4304新一代算法移植加密芯片,守护物联网设备和云服务安全
物联网·安全
雾里看山3 小时前
C语言之结构体
c语言·开发语言·笔记
网安-轩逸3 小时前
网络安全设备主要有什么
网络·安全·web安全
城主科技3 小时前
从零部署【国际互联网、ISP骨干网、互联网数据中心、企业数据中心、企业私网】组成的大型综合型网络环境部署。
网络·网络安全·华为·智能路由器
重生之我在20年代敲代码3 小时前
【C++入门】详解(中)
开发语言·c++·笔记
Xudde.4 小时前
Wireshark抓包教程(2024最新版个人笔记)
笔记·wireshark