《汇编语言》- 读书笔记 - 第3章-寄存器(内存访问):mov、add、sub、push、pop

news2024/11/24 19:55:18

《汇编语言》- 读书笔记 - 第3章-寄存器(内存访问)

  • 3.1 内存中字的存储
    • 问题 3.1
  • 3.2 DS 和 [address]
    • 问题 3.2
  • 3.3 字的传送
    • 问题 3.3
    • 问题 3.4
  • 3.4 mov、add、sub 指令
  • 3.5 数据段
    • 问题 3.5
    • 3.1~3.5 小结
    • 检测点 3.1
  • 3.6 栈
  • 3.7 CPU 提供的栈机制
    • 问题 3.6
  • 3.8 栈顶超界的问题
  • 3.9 push、pop 指令
    • 问题 3.7
    • 问题 3.8
    • 问题 3.9
    • 问题 3.10
    • 栈的综述
  • 3.10 栈段
    • 问题3.11
    • 问题 3.12
    • 段的综述
    • 检测点 3.2

3.1 内存中字的存储

1字 = 2字节

在这里插入图片描述
20000 = 4E20H 在内存中表示如图。从地址 0 开始
读一个字节,得到20H
读一个,得到4E20H (读取时先读到的是低字节,后读到高字节)
我们将起始地址为 N 的字单元简称为 N 地址字单元。

问题 3.1

对于图 3.1:

  1. 0 地址单元中存放的字节型数据是多少? 20H
  2. 0 地址字单元中存放的型数据是多少? 4E20H
  3. 2 地址单元中存放的字节型数据是多少? 12H
  4. 2 地址字单元中存放的型数据是多少? 0012H
  5. 1 地址字单元中存放的型数据是多少? 124EH

3.2 DS 和 [address]

CPU必须知道一个内存的单元地址,才能读写它。8086PC中,内存地址=段地址+偏移地址组成。
8086CPU 中有一个 ds 寄存器,通常用来存放要访问数据的段地址。
以下是从10000H单元读取1字节到al(如果是ax就是读一个字了,mov能见风使舵。)

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

从这段汇编可以看到:

  1. DS很害羞不让直接写,需要bx递给她。
  2. mov能把内存中的数据送进寄存器
  3. []表示一个内存地址。其中的0表示内存单元偏移地址。
  4. 省掉段地址,默认会用ds中的值。

问题 3.2

写几条指令,将 al 中的数据送入内存单元 10000H 中,思考后看分析。
在这里插入图片描述
为了便于查看,最开始就先把ax的内容改为9527

3.3 字的传送

正式明确:只要在 mov 指令中给出 16 位的寄存器就可以进行 16 位数据的传送。

问题 3.3

内存中的情况如图 3.2 所示,写出下面的指令执行后寄存器 ax,bx,cx 中的值。
在这里插入图片描述
在这里插入图片描述

  • 动手练习:
assume cs:codesg
codesg segment

start:	               ; ax		bx		cx
	mov ax, 1000H      ; 1000H
	mov ds, ax         ; 
	mov ax, ds:[0]     ; 1123H
	mov bx, ds:[2]     ;		6622H
	mov cx, ds:[1]     ;				2211H
	add bx, ds:[1]     ;		8833H
	add cx, ds:[2]     ; 				8833H
	
codesg ends
end start

这里注意:按书中是直接在Debug中打的指令,支持[0]。如果我们写成MASM汇编代码编译[0] 会被当值。加上ds才能正常识别为地址。
在这里插入图片描述

问题 3.4

内存中的情况如图 3.3 所示,写出下面的指令执行后内存中的值,思考后看分析

在这里插入图片描述
在这里插入图片描述

  • 动手练习:
assume cs:codesg
codesg segment

start:	               ; ax		bx		cx	|	00	01	02	03
	mov ax, 1000H      ; 1000H				|	23	11	22	11
	mov ds, ax         ;                    |
	mov ax, 11316      ; 2C34H              |    
	mov ds:[0], ax     ;                    |   34	2C
	mov bx, ds:[0]     ; 		2C34H       |
	sub bx, ds:[2]     ;        1B12H       |
	mov ds:[2], bx     ;                    |            12	1B

codesg ends
end start

注意:如果是汇编代码编译运行,记得带上段地址。(Debug中可以直接写偏移)
在这里插入图片描述

3.4 mov、add、sub 指令

mov、add、sub 指令都带有两个操作对象,可知 mov 指令可有以下形式:

指令目标来源示例
mov寄存器数据mov ax, 8
mov寄存器寄存器mov ax, bx
mov寄存器内存单元mov ax, [0]
mov内存单元寄存器mov [0], ax
mov段寄存器寄存器mov ds, ax
推导出:
mov寄存器段寄存器mov ax, ds
mov内存单元段寄存器mov [0], cs
mov段寄存器内存单元mov ds, [0]

add、sub 无法使用段寄存器。(源、目标都不行)

指令目标来源示例
add寄存器数据add ax, 8
add寄存器寄存器add ax, bx
add寄存器内存单元add ax, [0]
add内存单元寄存器add [0], ax
sub寄存器数据sub ax, 9
sub寄存器寄存器sub ax, bx
sub寄存器内存单元sub ax, [0]
sub内存单元寄存器sub [0], ax

在这里插入图片描述

3.5 数据段

在8086PC机中,可以将这样一组内存单元定义为一个段,用来存储数据:

  1. 一段连续的地址。
  2. 起始地址为 16 的倍数。
  3. 长度小于等于64KB。
    访问数据段中的数据需要用ds存放数据段的段地址,再根据需要使用相关指令访问具体单元。

问题 3.5

写几条指令,累加数据段中的前 3 个字型数据,思考后看分析。

mov ax, 123BH
mov ds, ax       ;123BH 送入 ds 中,作为数据段的段地址
mov ax, 0        ;用 ax 存放累加结果
add ax, [0]      ;将数据段第一个字(偏移地址为 0)加到 ax 中
add ax, [2]      ;将数据段第二个字(偏移地址为 2)加到 ax 中
add ax, [4]      ;将数据段第三个字(偏移地址为 4)加到 ax 中

注意,一个字型数据占两个单元,所以偏移地址是 0、2、4

  • 动手练习
    在这里插入图片描述

3.1~3.5 小结

  1. 字在内存中存储时,要用两个地址连续的内存单元来存放,字的低位字节存放在低地址单元中,高位字节存放在高地址单元中。
  2. mov 指令访问内存单元,可以在 mov 指令中只给出单元的偏移地址,此时,段地址默认在DS寄存器中。
  3. [address]表示一个偏移地址为 address 的内存单元。
  4. 在内存和寄存器之间传送字型数据时,高地址单元和高 8 位寄存器、低地址单元和低 8 位寄存器相对应。
  5. movaddsub 是具有两个操作对象的指令。jmp 是具有一个操作对象的指令。
  6. 可以根据自己的推测,在 Debug 中实验指令的新格式。

检测点 3.1

《汇编语言》- 读书笔记 - 检测点# 检测点 3.1

3.6 栈

是一种数据结构,它的特点是后进选出
我们可以把它理解成一个严谨的酸菜坛子,放进去的酸菜铺在下面放进去的铺在上面
当我们取出酸菜时,最先拿出来的就是坛子口处的酸菜。(也就是最后放进去的那片)

在这里插入图片描述 在这里插入图片描述

3.7 CPU 提供的栈机制

8086CPU 提供了PUSH(入栈)和 POP(出栈)两个最基本的指令用来以的方式访问内存空间。
push ax 将寄存器 ax 中的数据送入
pop ax栈顶取出数据送入 ax
操作以为单位进行。

下面举例说明,我们可以将 10000H~1000FH 这段内存当作栈来使用。
图 3.9 描述了下面一段指令的执行过程。
在这里插入图片描述
任意时刻,SS:SP 指向栈顶元素。
push 指令和 pop 指令执行时,CPU 从 SS 和 SP 中得到栈顶的地址。

  • push ax 的执行步骤:

    1. SP=SP-2SS:SP 指向当前栈顶前面的单元,以当前栈顶前面的单元为新的栈顶;
    2. 将 ax 中的内容送入 SS:SP 指向的内存单元处,SS:SP 此时指向新栈顶。

    图 3.10 描述了 8086CPU 对 push 指令的执行过程
    在这里插入图片描述

  • pop ax 的执行步骤:(执行过程和 push ax 刚好相反)

    1. SS:SP 指向的内存单元处的数据送入 ax 中;
    2. SP=SP+2SS:SP 指向当前栈顶下面的单元,以当前栈顶下面的单元为新的栈顶。

图 3.12 描述了 8086CPU 对 pop 指令的执行过程
在这里插入图片描述

问题 3.6

如果将 10000H~1000FH 这段空间当作栈,初始状态栈是空的,此时,SS=1000H,SP=? 思考后看分析。
在这里插入图片描述
分析:空栈时SS:SP的指向。

  1. 我们以10000H~1000FH为栈。当栈中只有一个元素时,如果再次POP按照规则SP=SP+2SS:SP的指向10010H
  2. 反过来推,如果当前是空栈,PUSHSP=SP-2栈顶元素在1000E,那么要满足这个结果,空栈时SS:SP的指向10010H

3.8 栈顶超界的问题

栈只是我们人为对内存中一个区域的使用规划。CPU只知道SS:SP指向栈顶,以及PUSHPOP
栈的边界也在我们的脑海里。需要我们自己来控制使用。
栈满时继续PUSH就会超界。
栈空时继续POP也会超界。
超界后就可能会意外的读写到栈外的数据,但是那段内存现在是谁在用,存的什么内容,对于我们当前来说是未知的(无意义的、随机的)
所以如果我们不小心修改了它,就可能造成其他程序发生错乱。当然我们使用这坨无意义的数据,我们当前的程序通常也会出问题。
在这里插入图片描述在这里插入图片描述

3.9 push、pop 指令

指令目标说明
push寄存器将一个寄存器中的数据入栈
push段寄存器将一个段寄存器中的数据入栈
push内存单元将一个内存字单元处的字入栈(注意: 栈操作都是以字为单位)
pop段寄存器出栈,用一个段寄存器接收出栈的数据
pop寄存器出栈,用一个寄存器接收出栈的数据
pop内存单元出栈,用一个内存字单元接收出栈的数据

如果只给内存单元的偏移地址段地址默认从 ds 中取。

问题 3.7

编程,将 10000H~1000FH 这段空间当作栈,初始状态栈是空的,将 AX、BX、DS中的数据入栈。
在这里插入图片描述
Debug 的 T 命令在执行修改寄存器 SS 的指令时,下一条指令也紧接着被执行。后面学到了,再回来补传送门。

问题 3.8

编程:

  1. 10000H~1000FH 这段空间当作栈,初始状态栈是空的;
  2. 设置 AX=001AHBX=001BH;
  3. 将 AX、BX 中的数据入栈;
  4. 然后将 AX、BX 清零;
  5. 从栈中恢复 AX、BX 原来的内容。
mov ax, 1000	
mov ss, ax
mov sp, 0010	; 初始化栈顶,栈的情况如图3.15(a)
mov ax, 001A
mov bx, 001B	
push ax			  
push bx			; ax、bx入栈,栈的情况如图3.15(b) 所示
sub ax, ax		; 将 ax 清零。也可以用mov ax, 0
				; sub ax,ax 的机器码占2字节。
				; mov ax,0 	的机器码占3字节。
sub bx, bx
pop bx			; 从栈中恢复 ax、bx 原来的数据,记得先进后出
pop ax			

pop 时与 push 顺序相反。数据保持原序。
在这里插入图片描述

问题 3.9

  1. 10000H~1000FH这段空间当作栈,初始状态栈是空的;
  2. 设置 AX=001AHBX=001BH;
  3. 利用栈,交换 AXBX 中的数据;

在这里插入图片描述
只要把 问题3.8 中 两个pop顺序调换一下就行了。
pop 时与 push 顺序相同。数据的顺序反转。

问题 3.10

如果要在 10000H 处写入字型数据 2266H,可以用以下的代码完成:

mov ax,1000H
mov ds,ax
mov ax,2266H
mov [0],ax

补全代码
分析,最后两句是将 ax 数据入栈,那前面缺的就是设置栈顶了。

mov ax, 1000
mov ss, ax
mov sp, 2
mov ax, 2266
push ax

栈的综述

  1. 8086CPU 提供了栈操作机制,方案如下。
    SS、SP 中存放栈顶的段地址偏移地址;
    提供入栈出栈指令,它们根据 SS:SP 指示的地址,按照栈的方式访问内存单元。
  2. push 指令的执行步骤: ①SP=SP-2; ②向SS:SP指向的字单元中送入数据。
  3. pop 指令的执行步骤: ①从SS:SP指向的字单元中读取数据; ②SP=SP+2
  4. 任意时刻,SS:SP 指向栈顶元素。
  5. 8086CPU 只记录栈顶,栈空间的大小我们要自己管理
  6. 来暂存以后需要恢复的寄存器的内容时,寄存器出栈的顺序要和入栈的顺序相反。
  7. push、pop 实质上是一种内存传送指令,注意它们的灵活应用。

栈是一种非常重要的机制,一定要深入理解,灵活掌握。

3.10 栈段

编程时可以将一组内存单元定义为一个段。
如将一段地址当栈空间来使用:

  1. 起始地址为16倍数;
  2. 长度N(N<=64KB)
  3. 一组连续的地址。

问题3.11

如果将 10000H~1FFFFH 这段空间当作栈段,初始状态栈是空的,此时,SS=1000HSP=?
分析:

  1. 栈中元素是字。(push、pop一次都是两个字节)
  2. 当只有一个元素时,SP 指向 FFFE (最后一个元素占 FFFE~FFFF
  3. 此时再POP一次,使栈为空,SP 指向 FFFE+2 = 0000

所以 SP=0

问题 3.12

一个栈段最大可以设为多少? 为什么?
答:一个栈段最大可以设为64KB。因为偏移地址取值范围0000~FFFF
当栈满时SP=0,继续PUSH,SP=SP-2 = FFFE
在这里插入图片描述

段的综述

我们可以将一段内存定义为一个段,用一个段地址指示段,用偏移地址访问段内的单元。这完全是我们自己的安排。
我们可以用一个段存放数据,将它定义为“数据段”;
我们可以用一个段存放代码,将它定义为“代码段”;
我们可以用一个段当作栈,将它定义为“栈段”。
我们可以这样安排,但若要让 CPU 按照我们的安排来访问这些段,就要:
对于数据段,将它的段地址放在 DS 中,用 mov、add、sub 等访问内存单元的指令时,CPU 就将我们定义的数据段中的内容当作数据来访问;
对于代码段,将它的段地址放在 CS 中,将段中第一条指令的偏移地址放在 IP 中,这样 CPU 就将执行我们定义的代码段中的指令;
对于栈段,将它的段地址放在 SS 中,将栈顶单元的偏移地址放在 SP 中,这样 CPU 在需要进行栈操作的时候,比如执行 push、pop 指令等,就将我们定义的栈段当作栈空间来用。
可见,不管我们如何安排,
CPU 将内存中的某段内容当作代码,是因 CS:IP 指向了那里;
CPU 将某段内存当作栈,是因为 SS:SP指向了那里。
我们一定要清楚,什么是我们的安排,以及如何让 CPU 按我们的安排行事。
要非常清楚 CPU 的工作机理,才能在控制 CPU 按照我们的安排运行的时候做到游刀有余。
比如我们将 10000H~1001FH 安排为代码段,并在里面存储如下代码:

mov ax, 1000H
mov ss, ax
mov sp, 0020H	; 初始化栈顶
mov ax, cs
mov ds, ax		; 设置数据段段地址
mov ax, [0]
add ax, [2]
mov bx, [4]
add bx, [6]
push ax
push bx
pop ax
pop bx

设置 CS=1000HIP=0,这段代码将得到执行。可以看到,在这段代码中,我们又将10000H~1001FH 安排为栈段数据段10000H-1001FH 这段内存,既是代码段,又是栈段和数据段。
一段内存,可以既是代码的存储空间,又是数据的存储空间,还可以是栈空间,也可以什么也不是。关键在于 CPU 中寄存器的设置,即 CS、I,SS、SP,DS 的指向。

检测点 3.2

《汇编语言》- 读书笔记 - 检测点# 检测点 3.2

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/571577.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于LSB实现文本、图片、压缩包的隐藏

关于LSB的相关介绍&#xff1a; LSB全称为 Least Significant Bit&#xff08;最低有效位&#xff09;&#xff0c;是一种基于图片最低有效位修改储存信息的隐写方法&#xff0c;在CTF杂项中经常会遇到&#xff0c;LSB属于空域算法中的一种&#xff0c;是将信息嵌入到图像点中…

OPCUA从入门到精通看这里就够了

本文将会从以下几个方面介绍 1.OPCUA是什么 2.OPCUA常用的工具有那些 3.OPCUA的官网 4.使用opcua常用的方法和功能介绍 5.根据官网自己封装了一个opcuaclient类&#xff0c;并说明每个方法的用处 6.根据4中的opcuaclient类自己写了demo 本文所有用到的资料在此下载包括U…

Android平台音视频推送选RTMP还是GB28181?

技术背景 早在2015年&#xff0c;我们发布了RTMP直播推送模块&#xff0c;那时候音视频直播这块场景需求&#xff0c;还不像现在这么普遍&#xff0c;我们做这块的初衷&#xff0c;主要是为了实现移动单兵应急指挥系统的低延迟音视频数据传输。好多开发者可能会疑惑&#xff0…

信息系统建设和服务能力评估证书CS

信息系统建设和服务能力评估体系CS简介 简介&#xff1a;本标准&#xff08;团标T/CITIF 001-2019&#xff09;是信息系统建设和服务能力评估体系系列标准的第一个&#xff0c;提出了对信息系统建设和服务提供者的综合能力要求。 发证单位&#xff1a;中国电子信息行业联合会。…

整型,浮点型,大小字节知识细节一网打尽!

目录 一. 整型 2.11 C语言内置整型 2.12整型在内存如何存储&#xff1f; 2.12 原码&#xff0c;反码&#xff0c; 补码 2.13 当 整型遇上unsigned 2.1 unsigned 与 signed 解析 2.2 printf 输出 有无符号数解析 2.3 有关练习 二. 浮点型 2.51 浮点型与整型在存储上的…

视频会议产品对比分析

内网视频会议系统如何选择&#xff1f;有很多单位为了保密&#xff0c;只能使用内部网络&#xff0c;无法连接互联网&#xff0c;那些SaaS视频会议就无法使用。在内网的优秀视频会议也有很多可供选择&#xff0c;以下是几个常用的&#xff1a; 1. 宝利通&#xff1a;它支持多种…

港联证券|新产品“内卷”,史上最火光伏展能否带动光伏板块行情

在光伏成为“能源老大”之前&#xff0c;指数何时能够跑赢A股股主要股指&#xff0c;或是散户关注的重点。 时隔两年&#xff0c;SNEC上海光伏展如约举办。本届展会吸引了3000余家光伏公司参展&#xff0c;累计50万人涌进场馆&#xff0c;现场人群拥挤度丝毫不逊于过去两年资金…

Navicat连接Oracle时报错ORA-28547

错误信息 这是因为Navicat自带的oci.dll并不支持oracle11g&#xff0c;网上这么说的&#xff0c;需要去官网下载支持的版本。 直接动手。 1. 先DBeaver的连接到oracle数据库&#xff08;为了查询版本&#xff09; 1.1 查询版本 SQL&#xff1a;select * from v$version;1.2 …

如何利用Linkage Mapper工具包评估栖息地碎片化程度详解(含实例分析)

✅创作者:陈书予 🎉个人主页:陈书予的个人主页 🍁陈书予的个人社区,欢迎你的加入: 陈书予的社区 🌟专栏地址: Linkage Mapper解密数字世界链接 文章目录 Linkage Mapper工具包评估栖息地碎片化程度详解1. 介绍1.1 简介1.2 ArcGIS概述1.3 Linkage Mapper工具包简介

生态伙伴 | 携手深圳科创学院,持续推动项目落地与成长

01 大赛介绍 中国硬件创新创客大赛始于2015年&#xff0c;由深圳华秋电子有限公司主办&#xff0c;至今已经成功举办八届&#xff0c;赛事范围覆盖华南、华东、华北三大地区&#xff0c;超10个省市区域。 大赛影响了超过45万工程师群体&#xff0c;吸引了35000多名硬创先锋报…

分享Python采集66个焦点图,总有一款适合您

分享Python采集66个焦点图&#xff0c;总有一款适合您 Python采集的66个焦点图下载链接&#xff1a;https://pan.baidu.com/s/1nHoPaUp2Bqtrs5d7J-XdwA?pwd3yfb 提取码&#xff1a;3yfb jQuery SuperSlide插件自适应banner大图焦点图片轮播切换特效 jQuerySwiper仿魅族幻灯…

3.复制Centos虚拟机并且安装Ansible

在2.VirtualBox安装CentOS 7已经创建好了CentOS_template&#xff0c;按下面的步骤&#xff0c;从已经创建好的模版&#xff0c;分别复制出来3个虚拟机&#xff1a;ansible-controller和ansible-target1和ansible-target2。 注意这里的MAC地址设定&#xff0c;要选择&#xff…

用Tushare获取股票信息

Tushare数据Tushare为金融数据分析提供便捷、快速的接口&#xff0c;与投研和量化策略无缝对接https://tushare.pro/register?reg593541 o(≧口≦)o 先别看着链接就走了&#xff0c;敲黑板。 教大家如何基础使用日线行情获取接口数据&#xff0c;不会告诉你们我就是为了骗积分…

spring security oauth2.0-密码式password

密码式(password)授权模式 简介 如果你高度信任对方应用,密码式授权模式也是被允许的. 密码模式,顾名思义,就是使用账号密码的形式在授权服务器上获取授权令牌, 但是这种令牌是不支持刷新令牌的. 这种方式一般是不建议使用的,因为它的高风险性, 但是如果只是两家应用之间的…

算法工程师的主要职责(合集)

算法工程师的主要职责 算法工程师的主要职责1 1、环境建模 根据设计的机器人方案&#xff0c;构建机器人的运动学模型、观测模型等概率学模型; 2、slam算法研发 研究基于多线激光雷达的slam算法&#xff0c;包括特征提取、数据关联、闭环检测等相关算法的开发; 3、定位算法研发…

gd32f103vbt6 串口OTA升级-4-从rk3399的串口升级1

一、需求&#xff1a; 因客户需求&#xff0c;觉得升级单片机程序需要打开设备的盖子&#xff0c;&#xff08;抽出设备&#xff0c;拧螺丝&#xff0c;挺费事的&#xff09;。 那能不能把单片机也做到linux系统下升级呢&#xff1f; 答案当然是可行的。&#xff08;这里有个…

Shopee|Lazada电商平台api接口,接入获取商品评论|根据关键词取商品列表API说明示例

Shopee和Lazada是东南亚地区广受欢迎的电商平台。它们的模式非常类似&#xff0c;都是以C2C&#xff08;消费者到消费者&#xff09;、B2C&#xff08;企业到消费者&#xff09;和O2O&#xff08;线上到线下&#xff09;为主要销售模式。用户可以在平台上购买商品或者将自己的商…

如何在华为OD机试中获得满分?Java实现【组装新的数组】一文详解!

✅创作者&#xff1a;陈书予 &#x1f389;个人主页&#xff1a;陈书予的个人主页 &#x1f341;陈书予的个人社区&#xff0c;欢迎你的加入: 陈书予的社区 &#x1f31f;专栏地址: Java华为OD机试真题&#xff08;2022&2023) 文章目录 1. 题目描述2. 输入描述3. 输出描述…

华为OD机试真题 Java 实现【查找重复代码】【2023Q1 100分】

一、题目描述 小明负责维护项目中的代码,需要查找出重复代码,用以支撑后续的代码优化,请你帮助小明找出重复的代码。 重复代码查找方法: 以字符串形式给定两行代码,找出两行代码中的最长公共子串。 如果不存在公共子串,返回空。 二、输入描述 输入两行代码。 三、…

深眸科技|机器视觉应用优势显著赋能生产,技术崛起获发展前景

近年来&#xff0c;机器视觉已经逐渐渗透进工业制造领域的各个方面&#xff0c;并已经成为工业自动化和智能化的核心&#xff0c;无论是“中国制造2025”还是“工业4.0”都离不开机器视觉&#xff0c;机器视觉将为智能制造打开一个新的世界。 随着人工智能、云计算、5G等技术的…