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

2024-05-30 04:04

本文主要是介绍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
  2. 设置初始SP

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

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

这篇关于8086 汇编笔记(二):寄存器(内存访问)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1015530

相关文章

Redis实现高效内存管理的示例代码

《Redis实现高效内存管理的示例代码》Redis内存管理是其核心功能之一,为了高效地利用内存,Redis采用了多种技术和策略,如优化的数据结构、内存分配策略、内存回收、数据压缩等,下面就来详细的介绍... 目录1. 内存分配策略jemalloc 的使用2. 数据压缩和编码ziplist示例代码3. 优化的

深入解析C++ 中std::map内存管理

《深入解析C++中std::map内存管理》文章详解C++std::map内存管理,指出clear()仅删除元素可能不释放底层内存,建议用swap()与空map交换以彻底释放,针对指针类型需手动de... 目录1️、基本清空std::map2️、使用 swap 彻底释放内存3️、map 中存储指针类型的对象

Python内存优化的实战技巧分享

《Python内存优化的实战技巧分享》Python作为一门解释型语言,虽然在开发效率上有着显著优势,但在执行效率方面往往被诟病,然而,通过合理的内存优化策略,我们可以让Python程序的运行速度提升3... 目录前言python内存管理机制引用计数机制垃圾回收机制内存泄漏的常见原因1. 循环引用2. 全局变

Python学习笔记之getattr和hasattr用法示例详解

《Python学习笔记之getattr和hasattr用法示例详解》在Python中,hasattr()、getattr()和setattr()是一组内置函数,用于对对象的属性进行操作和查询,这篇文章... 目录1.getattr用法详解1.1 基本作用1.2 示例1.3 原理2.hasattr用法详解2.

通过配置nginx访问服务器静态资源的过程

《通过配置nginx访问服务器静态资源的过程》文章介绍了图片存储路径设置、Nginx服务器配置及通过http://192.168.206.170:8007/a.png访问图片的方法,涵盖图片管理与服务... 目录1.图片存储路径2.nginx配置3.访问图片方式总结1.图片存储路径2.nginx配置

MySQL 内存使用率常用分析语句

《MySQL内存使用率常用分析语句》用户整理了MySQL内存占用过高的分析方法,涵盖操作系统层确认及数据库层bufferpool、内存模块差值、线程状态、performance_schema性能数据... 目录一、 OS层二、 DB层1. 全局情况2. 内存占js用详情最近连续遇到mysql内存占用过高导致

最新Spring Security的基于内存用户认证方式

《最新SpringSecurity的基于内存用户认证方式》本文讲解SpringSecurity内存认证配置,适用于开发、测试等场景,通过代码创建用户及权限管理,支持密码加密,虽简单但不持久化,生产环... 目录1. 前言2. 因何选择内存认证?3. 基础配置实战❶ 创建Spring Security配置文件

java内存泄漏排查过程及解决

《java内存泄漏排查过程及解决》公司某服务内存持续增长,疑似内存泄漏,未触发OOM,排查方法包括检查JVM配置、分析GC执行状态、导出堆内存快照并用IDEAProfiler工具定位大对象及代码... 目录内存泄漏内存问题排查1.查看JVM内存配置2.分析gc是否正常执行3.导出 dump 各种工具分析4.

WinForm跨线程访问UI及UI卡死的解决方案

《WinForm跨线程访问UI及UI卡死的解决方案》在WinForm开发过程中,跨线程访问UI控件和界面卡死是常见的技术难题,由于Windows窗体应用程序的UI控件默认只能在主线程(UI线程)上操作... 目录前言正文案例1:直接线程操作(无UI访问)案例2:BeginInvoke访问UI(错误用法)案例

怎样通过分析GC日志来定位Java进程的内存问题

《怎样通过分析GC日志来定位Java进程的内存问题》:本文主要介绍怎样通过分析GC日志来定位Java进程的内存问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、GC 日志基础配置1. 启用详细 GC 日志2. 不同收集器的日志格式二、关键指标与分析维度1.