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

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

一、内存中字的存储

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

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

现在有以下几个问题

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

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

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

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

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

注意: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
  1. 设置初始SP
  • 初始SP = 栈段大小 = 10000H

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

相关文章
|
29天前
|
存储 前端开发 Java
Kotlin教程笔记 - MVVM架构怎样避免内存泄漏
Kotlin教程笔记 - MVVM架构怎样避免内存泄漏
26 2
|
23天前
|
传感器 人工智能 物联网
C 语言在计算机科学中尤其在硬件交互方面占据重要地位。本文探讨了 C 语言与硬件交互的主要方法,包括直接访问硬件寄存器、中断处理、I/O 端口操作、内存映射 I/O 和设备驱动程序开发
C 语言在计算机科学中尤其在硬件交互方面占据重要地位。本文探讨了 C 语言与硬件交互的主要方法,包括直接访问硬件寄存器、中断处理、I/O 端口操作、内存映射 I/O 和设备驱动程序开发,以及面临的挑战和未来趋势,旨在帮助读者深入了解并掌握这些关键技术。
40 6
|
4天前
|
存储 缓存 数据安全/隐私保护
DMA(Direct Memory Access):直接内存访问
DMA(Direct Memory Access)是一种允许外设直接与内存进行数据传输的技术,无需 CPU 干预。它通过减轻 CPU 负担、提高数据传输效率来提升系统性能。DMA 的工作模式包括直接模式和 FIFO 模式,数据传输方式有单字传送和块传送,寻址模式有增量寻址和非增量寻址。通过缓存一致性协议、同步机制、数据校验和合理的内存管理,DMA 确保了数据在内存中的一致性和完整性。
28 0
|
1月前
|
存储 编译器 Linux
【c++】类和对象(上)(类的定义格式、访问限定符、类域、类的实例化、对象的内存大小、this指针)
本文介绍了C++中的类和对象,包括类的概念、定义格式、访问限定符、类域、对象的创建及内存大小、以及this指针。通过示例代码详细解释了类的定义、成员函数和成员变量的作用,以及如何使用访问限定符控制成员的访问权限。此外,还讨论了对象的内存分配规则和this指针的使用场景,帮助读者深入理解面向对象编程的核心概念。
86 4
|
2月前
|
缓存 算法 数据处理
如何选择合适的内存访问模式
【10月更文挑战第20天】如何选择合适的内存访问模式
53 1
|
2月前
|
存储 容器
内存越界访问(Out-of-Bounds Access)
【10月更文挑战第12天】
253 2
|
2月前
|
Rust 编译器
|
2月前
|
存储 弹性计算 算法
前端大模型应用笔记(四):如何在资源受限例如1核和1G内存的端侧或ECS上运行一个合适的向量存储库及如何优化
本文探讨了在资源受限的嵌入式设备(如1核处理器和1GB内存)上实现高效向量存储和检索的方法,旨在支持端侧大模型应用。文章分析了Annoy、HNSWLib、NMSLib、FLANN、VP-Trees和Lshbox等向量存储库的特点与适用场景,推荐Annoy作为多数情况下的首选方案,并提出了数据预处理、索引优化、查询优化等策略以提升性能。通过这些方法,即使在资源受限的环境中也能实现高效的向量检索。
|
3月前
|
缓存 Java 测试技术
谷粒商城笔记+踩坑(11)——性能压测和调优,JMeter压力测试+jvisualvm监控性能+资源动静分离+修改堆内存
使用JMeter对项目各个接口进行压力测试,并对前端进行动静分离优化,优化三级分类查询接口的性能
116 10
谷粒商城笔记+踩坑(11)——性能压测和调优,JMeter压力测试+jvisualvm监控性能+资源动静分离+修改堆内存
|
2月前
|
存储 前端开发 Java
Kotlin教程笔记 - MVVM架构怎样避免内存泄漏
Kotlin教程笔记 - MVVM架构怎样避免内存泄漏