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

相关文章

Linux内存泄露的原因排查和解决方案(内存管理方法)

《Linux内存泄露的原因排查和解决方案(内存管理方法)》文章主要介绍了运维团队在Linux处理LB服务内存暴涨、内存报警问题的过程,从发现问题、排查原因到制定解决方案,并从中学习了Linux内存管理... 目录一、问题二、排查过程三、解决方案四、内存管理方法1)linux内存寻址2)Linux分页机制3)

解读静态资源访问static-locations和static-path-pattern

《解读静态资源访问static-locations和static-path-pattern》本文主要介绍了SpringBoot中静态资源的配置和访问方式,包括静态资源的默认前缀、默认地址、目录结构、访... 目录静态资源访问static-locations和static-path-pattern静态资源配置

Java循环创建对象内存溢出的解决方法

《Java循环创建对象内存溢出的解决方法》在Java中,如果在循环中不当地创建大量对象而不及时释放内存,很容易导致内存溢出(OutOfMemoryError),所以本文给大家介绍了Java循环创建对象... 目录问题1. 解决方案2. 示例代码2.1 原始版本(可能导致内存溢出)2.2 修改后的版本问题在

大数据小内存排序问题如何巧妙解决

《大数据小内存排序问题如何巧妙解决》文章介绍了大数据小内存排序的三种方法:数据库排序、分治法和位图法,数据库排序简单但速度慢,对设备要求高;分治法高效但实现复杂;位图法可读性差,但存储空间受限... 目录三种方法:方法概要数据库排序(http://www.chinasem.cn对数据库设备要求较高)分治法(常

Redis多种内存淘汰策略及配置技巧分享

《Redis多种内存淘汰策略及配置技巧分享》本文介绍了Redis内存满时的淘汰机制,包括内存淘汰机制的概念,Redis提供的8种淘汰策略(如noeviction、volatile-lru等)及其适用场... 目录前言一、什么是 Redis 的内存淘汰机制?二、Redis 内存淘汰策略1. pythonnoe

Java访问修饰符public、private、protected及默认访问权限详解

《Java访问修饰符public、private、protected及默认访问权限详解》:本文主要介绍Java访问修饰符public、private、protected及默认访问权限的相关资料,每... 目录前言1. public 访问修饰符特点:示例:适用场景:2. private 访问修饰符特点:示例:

Java内存泄漏问题的排查、优化与最佳实践

《Java内存泄漏问题的排查、优化与最佳实践》在Java开发中,内存泄漏是一个常见且令人头疼的问题,内存泄漏指的是程序在运行过程中,已经不再使用的对象没有被及时释放,从而导致内存占用不断增加,最终... 目录引言1. 什么是内存泄漏?常见的内存泄漏情况2. 如何排查 Java 中的内存泄漏?2.1 使用 J

Python 标准库time时间的访问和转换问题小结

《Python标准库time时间的访问和转换问题小结》time模块为Python提供了处理时间和日期的多种功能,适用于多种与时间相关的场景,包括获取当前时间、格式化时间、暂停程序执行、计算程序运行时... 目录模块介绍使用场景主要类主要函数 - time()- sleep()- localtime()- g

使用Python实现批量访问URL并解析XML响应功能

《使用Python实现批量访问URL并解析XML响应功能》在现代Web开发和数据抓取中,批量访问URL并解析响应内容是一个常见的需求,本文将详细介绍如何使用Python实现批量访问URL并解析XML响... 目录引言1. 背景与需求2. 工具方法实现2.1 单URL访问与解析代码实现代码说明2.2 示例调用

关于Java内存访问重排序的研究

《关于Java内存访问重排序的研究》文章主要介绍了重排序现象及其在多线程编程中的影响,包括内存可见性问题和Java内存模型中对重排序的规则... 目录什么是重排序重排序图解重排序实验as-if-serial语义内存访问重排序与内存可见性内存访问重排序与Java内存模型重排序示意表内存屏障内存屏障示意表Int