《汇编语言》- 读书笔记 - 第5章- [BX]和 loop 指令

news2024/12/23 14:49:58

《汇编语言》- 读书笔记 - 第5章- [BX]和 loop 指令

  • 5.1 [BX]
    • 问题 5.1
  • 5.2 Loop 指令
    • 任务 1
    • 任务 2
    • 任务 3
    • 程序 5.1
    • 问题 5.2
    • 问题 5.2
  • 5.3 在 Debug 中跟踪用 loop 指令实现的循环程序
  • 5.4 Debug 和汇编编译器 masm 对指令的不同处理
    • Debug
    • MASM
  • 5.5 loop 和[bx]的联合应用
    • 程序 5.5
    • 问题 5.4
    • 程序 5.6
  • 5.6 段前缀
  • 5.7 一段安全的空间
  • 5.8 段前缀的使用
    • 程序 5.8
    • 程序 5.9
  • 实验4 [bx]和 loop 的使用

  1. [bx]和内存单元的描述
指令段地址偏移地址说明
mov ax, [0]ds0将内存 ds:0 处的单元中的内容,送入 ax
mov al, [0]ds0将内存 ds:0 处的字节单元中的内容,送入 ax 的低8位
mov ax, [bx]dsbx中的值将内存 ds:[bx] 处的单元中的内容,送入 ax
mov al, [bx]dsbx中的值将内存 ds:[bx]处的字节单元中的内容,送入 ax 的低8位
  1. loop
    loop 指令表示循环。

  2. 定义的描述性的符号:“()”
    书中约定:()括号用来表示寄存器内存中的内容。
    ()中可以入:寄存器名、段寄存器名、内存单元的物理地址。

(ax)表示 ax 中的内容;
(al)表示 al 中的内容;
(20000H)表示内存 20000H 单元的内容(()中的内存单元的地址为物理地址);
((ds)*16+(bx))表示:内层()从ds和bx取出值,算出结果后当用一个物理地址,外层()从内存地址取出内容。

  1. ax 中的内容为 0010H,可以这样来描述: (ax)=0010H;
  2. 2000:1000 处的内容为 0010H,可以这样来描述: (21000H)=0010H;
  3. 对于 mov ax,[2]的功能,可以这样来描述:(ax)=((ds)*16+2);
  4. 对于 mov [2],ax 的功能,可以这样来描述:((ds)*16+2)=(ax);
  5. 对于 add ax,2 的功能,可以这样来描述: (ax)=(ax)+2;
  6. 对于 add ax,bx 的功能,可以这样来描述:(ax)=(ax)+(bx);
  7. 对于 push ax 的功能,可以这样来描述:
(sp)=(sp)-2
((ss)*16+(sp))=(ax)
  1. 对于 pop ax 的功能,可以这样来描述:
(ax)=((ss)*16+(sp))
(sp)=(sp)+2
  1. 约定符号 idata 表示常量
    书中约定: idata 表示常量。
    书中约定便于沟通,并非真的合法指令。

mov ax,[idata] 就代表 mov ax,[1]mov ax,[2]mov ax,[3]
mov bx, idata 就代表 mov bx,1mov bx,2mov bx,3
mov ds, idata 就代表 mov ds,1mov ds,2

5.1 [BX]

mov ax, [bx]
功能: bx 中存放的数据作为一个偏移地址 EA,段地址 SA 默认在 ds 中,将 SA:EA处的数据送入 ax 中。
即: (ax)=((ds)*16+(bx)).

mov[bx], ax
功能: bx 中存放的数据作为一个偏移地址 EA,段地址 SA 默认在 ds 中,将 ax 中的数据送入内存 SA:EA 处。即:((ds)*16+(bx))=(ax)。

问题 5.1

程序和内存中的情况如图 5.1 所示,写出程序执行后,21000H~21007H 单元中的内容。
在这里插入图片描述

5.2 Loop 指令

通常使用 loop 实现循环功能, cx 中存放循环次数。指令的格式是: loop 标号

CPU 执行 loop 指令的时候,分两步:

  1. (cx)=(cx) - 1;
  2. 判断 cx != 0 则:转至标号处执行,否则:向下继续执行。

任务 1

编程计算 2^2,结果存在 ax 中。
在这里插入图片描述

任务 2

编程计算 2^3

mov ax, 2
add ax, ax
add ax, ax

任务 3

编程计算 2^12

mov ax, 2
add ax, ax ; 重复 11

用于引出 loop 循环

程序 5.1

assume cs:abc	
abc segment		
	mov ax, 2
	
	mov cx, 11	; 循环 11 次
 s: add ax, ax
	loop s		; cx-1 后如果不为 0,转到 s 处执行
	
	mov ax, 4c00H
	int 21H		
abc ends		
end

初始为 2 再 add ax, ax 11 次实现 2^12
在这里插入图片描述

问题 5.2

编程,用加法计算 123 * 236,结果存在 ax 中。
分析:可用循环完成,123 * 236 等于 123相加236次。

assume cs:abc	
abc segment		
	mov ax, 123
	mov cx, 236
 s: add ax, 123
	loop s		
	mov ax, 4c00H
	int 21H		
abc ends		
end

问题 5.2

改进程序 5.2,提高 123 * 236 的计算速度。
分析:123 * 236 等于 123相加236次。也可以是 236相加123次。

assume cs:abc	
abc segment		
	mov ax, 236
	mov cx, 123
 s: add ax, 236
	loop s		
	mov ax, 4c00H
	int 21H		
abc ends		
end

5.3 在 Debug 中跟踪用 loop 指令实现的循环程序

debug 中 t、p、g 的用法,不再赘述,详见:《汇编语言》- 读书笔记 - 实验1 查看 CPU 和内存,用机器指令和汇编指令编程

5.4 Debug 和汇编编译器 masm 对指令的不同处理

Debug

指令说明
mov ax, [0]将内存中 ds:0 的内容送进 ax

MASM

指令说明
mov al, [0](al)=0,将常量 0 送入 al中 (与 mov al,0 含义相同);
mov al, ds:[0](al)=((ds)*16+0),将内存单元中的数据送入 al 中;
mov al, [bx](al)=((ds)*16+(bx)),将内存单元中的数据送入 al 中;
mov al,ds:[bx]等同 mov al, [bx]

总结:在masm中如果偏移以常量表示,则要显示指定段地址。

5.5 loop 和[bx]的联合应用

计算 ffff:0~ffff:B 单元中的数据的和,结果存储在 dx 中。
分析:

  1. dx放不放的下?
    答:0到b最多12个FF = 11EE,dx 有两字节最大存 FFFF,因此空间没问题。
  2. ffff:0~ffff:B的数能否直接在 dx中累加?
    答:不行。因为ffff:0~ffff:B中是字节。dx是字(占两个字节。)因为需要另一个寄存器做临时中转。
  3. 能否直接用 dl 累加?
    当然也不行。因为累加结果超过FF,只用dl会溢出。
    用临时工ax。比如 (al) = (ffff*16+0), (ah) = 0。把字节放进,值不变。

程序 5.5

assume cs:code
code segment
	mov ax, 0ffffh		;数值不能以字母开头,故前面加 0 
	mov ds, ax			;设置(ds)=ffffh
	
	mov dx, 0			;初始化累加寄存器,(dx)=0
	
	mov al, ds:[0]		;从内存取值,给临时工 ax。
	mov ah, 0			;清空高位
	add dx, ax			;执行累加
	
	; 累计操作共重复12次。	
	
	mov ax, 4c00h		
	int 21h
code ends
end

问题 5.4

程序5.5的代码有问题,重复多次,应该使用 loop 实现循环。

程序 5.6

assume cs:code
code segment
	mov ax, 0ffffh		;数值不能以字母开头,故前面加 0 
	mov ds, ax			;设置(ds)=ffffh
	mov bx, 0			;bx中存偏移地址,初始为 0
	
	mov dx, 0			;初始化累加寄存器,(dx)=0
	mov cx, 12			;设置循环次数
 s: mov al, [bx]		;从内存取值,给临时工 ax
	mov ah, 0			;清空高位
	add dx, ax			;执行累加
	inc bx				;bx+1让偏移地址指向下一个字节
	loop s				;检测循环条件,符合就循环,否则向下继续
	
	mov ax, 4c00h		
	int 21h
code ends
end

在这里插入图片描述

5.6 段前缀

mov ax, ds:[bx]
mov ax, cs:[bx]
mov ax, ss:[bx]
mov ax, es:[bx]
mov ax, ss:[0]
mov ax, cs:[0]

这些出现在访问内存单元的指令中,用于显式地指明内存单元的段地址ds:、cs:、ss、es 在汇编语言中称为段前缀

5.7 一段安全的空间

在一般的 PC 机中,DOS 方式下,DOS 和其他合法的程序一般都不会使用 0:200~0:2ff(00200h~002ffh)这 256 个字节的空间。
为了谨慎起见,在进入 DOS 后,我们可以先用Debug 查看一下,如果 0:200~0:2ff 单元的内容都是 0 的话,则证明确实没有人使用这里。

5.8 段前缀的使用

程序 5.8

书先写了一个不合理的版本,在循环中更改段前缀。引出后话。

程序 5.9

这次用两个段寄存器,分别破防源与目标。省去了循环中捣腾段寄存器的烦恼。

assume cs:code
code segment
	mov ax, 0ffffh
	mov ds, ax			; 设置源段前缀
	mov ax, 0020h
	mov es, ax			; 设置目标源段前缀
	
	mov bx, 0			; 偏移量从0开始(源和目标皆从0开始,正好共用)
	mov cx, 12			; 循环12次
 s:mov dl, ds:[bx]		; 从源内存取值,送入dl
	mov es:[bx], dl		; 从 dl 取值送入目标内存
	inc bx				; 偏移地址向前移动
	loop s				; 判断cx不为0就循环,否则继续向下。
	
	mov ax, 4c00h
	int 21h
code ends
end	

实验4 [bx]和 loop 的使用

《汇编语言》- 读书笔记 - 实验4 [bx]和 loop 的使用

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

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

相关文章

大数据项目实战之数据仓库:电商数据仓库系统——第9章 数仓开发之DWD层

文章目录 第9章 数仓开发之DWD层9.1 交易域加购事务事实表9.2 交易域下单事务事实表9.3 交易域取消订单事务事实表9.4 交易域支付成功事务事实表9.5 交易域退单事务事实表9.6 交易域退款成功事务事实表9.7 交易域购物车周期快照事实表9.8 工具域优惠券领取事务事实表9.9 工具域…

Python论文复现:VMD之自适应选择分解模态数K值

Python论文复现:《基于稀疏指标的优化变分模态分解方法》 信号分解方法中,虽然变分模态分解(Variational Mode Decomposition, VMD)有严格的数学推导,能有效抑制端点效应、模态混叠等问题,但其分解模态数需…

Docker笔记9 | Docker中网络功能知识梳理和了解

9 | Docker中网络功能知识梳理和了解 1 外部访问容器1.1 访问方式1.2 映射所有接口地址1.3 映射到指定地址的指定端口1.4 映射到指定地址的任意端口1.5 查看映射端口配置 2 容器互联2.1 新建网络2.2 连接容器 3 配置DNS 简单说:Docker 允许通过外部访问容器或容器互…

Python中的全局变量与局部变量

1 定义 全局变量指的是在整个python文件中定义的变量,而局部变量是在函数内部定义的变量。 a 1 def yang_func():b 2 从以上代码中可以看出,变量a是全局变量,变量b是定义在yang_func()函数的内部,因此b是局部变量。 2 使用范…

云原生之部署Docker管理面板SimpleDocker

云原生之部署Docker管理面板SimpleDocker 一、SimpleDocker介绍1. SimpleDocker简介2. SimpleDocker特点 二、本地环境介绍1. 本地环境规划2. 本次实践介绍 三、本地环境检查1.检查Docker服务状态2. 检查Docker版本3.检查docker compose 版本 四、下载SimpleDocker镜像五、部署…

【GD32开发】一、GD32F103 TIMER0 PWM死区时间计算

一、PWM死区时间如何计算? GD32F103的数据手册关于死区时间控制的公式如上图。 DTCFG的值为 设置死区结构体的寄存器值 tDTS_CK的值为 系统时钟的时钟周期。 如:GD32F103的系统时钟是108Mhz, 则tDTS_CK 1/108Mhz 9.26ns。( stm32的这个值跟定时器的…

如何从 Android 内部存储中恢复已删除的照片?

我们使用手机录制的照片和视频通常存储在手机的内存中。我们存储它们以记住我们生活的美丽。然而,在管理这些照片的过程中,一些用户却发现自己不小心删除了这些照片,这很尴尬。 如果您的 Android 设备遇到过此类问题,那么您来对地…

SpringBoot日记本系统小白部署指南

哈喽,大家好,我是兔哥。 之前写的SpringBoot日记本系统备受好评,考虑到还是有很多小伙伴不会部署,所以这一篇文章就单独来讲一下部署步骤吧。 需要资源 idea(破不破解都行) MySQL(最好5.7以…

redis高级篇一

redis 是多线程还是单线程 redis单线程的操作 主要是指redis的网路IO和键值对的读写是由一个线程来完成的,Redis在处理客户端的请求时,包括获取(socket 读),解析,执行,内容返回(so…

linux(动静态库)

目录: 1.文件时间的概念 2.动态库和静态库 3.如何制作动静态库 -------------------------------------------------------------------------------------------------------------------------------- 1.文件时间的概念 我们现在就开始学习这三个时间分别表示了什…

AI百科:一个开启人工智能时代的综合性平台

无论是人工智能的快速发展还是AI技术在各个领域的广泛应用,都让我们对智能未来充满了期待和好奇。随着科技的进步,发现了一个好网站,一个集合了丰富AI工具和产品介绍的综合性网站—— AI百科。 在人工智能(AI)领域的快…

【实用工具 - vscode】实现Linux服务器的远程操控

🌟hello,各位读者大大们你们好呀🌟 🍭🍭系列专栏:【计算机工具】 ✒️✒️本篇内容:vscode的下载安装,常见插件及详细安装方法,插件停用及卸载,vscode快捷键 …

如何将文件制作成二维码

日常生活和工作中,为了让大家更方便的查阅文件,可将文件生成二维码,打印在通知书、会议要求,或是直接用“二维码”分享。通过草料二维码可以将多种类型的文件快速生成文件二维码,微信扫码查看即可查看和下载文件。 ● …

项目风险管理的四个阶段,你了解多少?

项目风险管理是项目管理的一部分,目的是保证项目总目标的实现。 风险管理包括风险识别、风险估计、风险解决和风险监控。风险管理贯穿在项目中的每个环节,在项目的生命周期中监控风险是非常重要的手段。 风险管理包含四个阶段: 1、风险识别…

从需求分析到功能扩展:打破瓶颈,构建智能采购管理软件

在当今快速发展的商业环境下,采购管理已成为企业发展的关键环节之一。如何在采购管理中快速响应市场需求、协调供应链、提高效率和降低成本,是摆在企业面前的一个巨大挑战。因此,打破瓶颈,构建智能采购管理软件成为了迫切的需求。…

内蒙古自治区住房和城乡建设分析及解决方案

安科瑞 徐浩竣 江苏安科瑞电器制造有限公司 zx acrelxhj 摘 要:为深入贯彻落实《国务院办公厅关于印发新能源汽车产业发展规划(2021—2035年)的通知》(国办发 ﹝2020﹞39号)、《国家发展改革委等部门关于进一步提升…

一文读懂如何将 Rancher 下游集群升级到 Kubernetes v1.25

介 绍 最初在 Kubernetes v1.21 中被弃用的 PodSecurityPolicy API,已经在 Kubernetes v1.25 中被完全删除。由于 API 被移除,你无法在 Kubernetes v1.25 集群中创建、编辑或查询 PodSecurityPolicy 资源。此外,由于其准入控制器已被移除&am…

JAVA-类隔离机制

一、类加载: 1、类加载:Java源程序经过编译器编译后变成字节码,字节码由虚拟机解释执行,虚拟机将每一条要执行的字节码加载到内存,发给解释器,解释器将其翻译成特定机器上的机器码,然后在特定的…

Windows 上安装和启动 Nacos 2.2.2 最新版本

文章目录 前言版本声明本地启动1. 下载 Nacos2. 开启鉴权配置3. 持久化数据库4. 启动 Nacos5. 启动测试 联系我 前言 本文旨在为您详细介绍如何安装和启动 Nacos 2.2.2 的最新版本,以及为 youlai-mall 开源商城版本的升级做好准备工作。 版本声明 名称版本操作系…

企业工程项目管理系统源码-全面的工程项目管理

​ ​工程项目管理系统是指从事工程项目管理的企业(以下简称工程项目管理企业)受业主委托,按照合同约定,代表业主对工程项目的组织实施进行全过程或若干阶段的管理和服务。 如今建筑行业竞争激烈,内卷严重&#xff0c…