这一章主要介绍什么是[BX]以及loop(循环)指令怎么使用,loop和[BX]又怎么样相结合,段前缀又是什么鬼,以及如何使用段前缀。
 
1、[BX]的概念
     [BX]和[0]类似,[0]表示内存单元的偏移地址是0。要完整描述一个内存单元,需要两种信息:内存单元的地址,内存单元的长度(类型)。[BX]同样也表示一个内存单元,它的偏移地址在bx中,比如指令:mov ax,[bx]。这里我们以一个程序为例:
      assume cs:codesg
codesg segment
start: mov ax,2000H
mov ds,ax
mov al,[]
mov bl,[]
mov cl,[]
mov dl,[]
mov ax,4C00H
int 21H
codesg ends
end start
     进行编译,连接之后,使用debug来调试这个程序。对于编译器而言,[0]的中括号是不存在的,所以会出现把0放到al中,把1放到bl中。所以,我们要想偏移地址为某个数,所对应的内存单元传递到寄存器当中,就需要进行两步操作:
     mov bx,0
     mov ax,[bx]
     这样做的话,就可以实现将偏移地址为0对应的内存单元的值传递给寄存器了。
 
2、loop
     这是一个做循环操作的指令,指令格式:loop 标号。
     CPU执行loop指令时,要进行两个步骤的操作:
          (1)(cx)=(cx)-1(这里的cx放在一个括号里面,意思是cx的值)
          (2)判断cx是不是为零,不为零的话转到标号出执行程序。
     所以,loop和cx是有直接联系的,即cx的值影响着loop的执行结果。所以cx的值也就是指的是loop的循环次数,我们可以想到高级语言中,使用循环时(比如for循环),我们都会定义一个变量,来作为循环的条件,这个变量的值也就是循环的次数。
     现在我们来看用汇编来计算2^2结果的代码:
 assume cs:code
code segment
mov ax,
add ax,ax mov ax,4c00h
int 21h
code ends
end
     计算2^3也是类似的,代码如下:   
 assume cs:code
code segment
mov ax,
add ax,ax
add ax,ax mov ax,4c00h
int 21h
code ends
end
     那么计算2^12,我们就要使用循环来做了,不然重复的代码太多,这个时候我们就要使用到loop指令了,代码如下:
 assume cs:code
code segment
mov ax,
mov cx,
s:add ax,ax
loop s mov ax,4c00h
int 21h
code ends
end
     上面的代码中,s就是标号,这个标号可以是任何你自己定义的内容,实际上s标明了一个地址,这个地址处有一个指令:add ax,ax。cx我们定义的值为11,因为要算2^12,所以要循环11次。循环时,cx会减1,循环一次减一次,直到cx为0,停止循环。我们可以使用debug调试编译连接好的程序:
     
     从上面的内容,我们可以得到cx和loop指令互相配合的三个关键点:
     (1)、在cx中存放循环次数
     (2)、loop指令标号所标识的地址要在前面
     (3)、要循环执行的程序段,写在标号和loop指令之间。
 
3、loop和[bx]的联合使用
     我们先从几个问题入手:计算ffff:0~ffff:b单元中的数据的和,结果存储在dx中。
     (1)、运算后的结果是否会超出dx所能存储的值的范围?
          ffff:0~ffff:b内存单元中的数据是字节型数据,范围是0~256,12个这样的数据相加,结果是不会比65535更大的,因此dx中是可以存储下的。
     (2)、能够将ffff:0~ffff:b直接累加到dx当中呢?
          不行,因为ffff:0~ffff:b中的数据是8位的,不能直接加到16位寄存器dx中。
     (3)、能否将ffff:0~ffff:b中的数据累加到dl中,并设置(dh)=0,从而实现累加到dx中呢?
          不行,dl是一个8位寄存器,能容纳的数据的范围在0~255之间,ffff:0~ffff:b中的数据也是8位的,将12个8位的数据累加到一个8位寄存器中,可能会出现进位丢失的情况。
     (4)、那么到底应该怎样将这段内存单元中的数据的和存储到dx中呢?
          就是使用一个16位寄存器来做中介,将内存单元中的8位数据赋值到一个16位寄存器ax中,再将这个ax中的数据加到dx上,从而使得运算对象的类型能够的到匹配(ax,dx都是16进制)并且结果不会越界。
     因为这里要进行12次的相加,因此要使用到loop指令进行循环相加的操作,具体代码如下:
 assume cs:codeseg
codeseg segment mov ax,0ffffh
mov ds,ax ;初始化ds:bx 指向ffff:0内存单元
mov bx, mov dx, ;初始化累加寄存器dx
mov cx, ;初始化循环计数寄存器cx s: mov al,[bx]
mov ah,
add dx,ax ;间接向dx中加上((ds)*16+(bx))单元中的数值
inc bx ;ds:bx指向下一个单元
loop s mov ax,4c00h
int 21h codeseg ends
end
 
4、Debug的G命令和P命令
     当我们对程序进行调试时,循环的次数很大时,我们不可能一次一次的执行t命令,因此要使用G命令或者P命令。G 循环结束的偏移地址,这样就可以一次执行完循环的内容。P,直接执行完循环的内容。
 
5、一段安全的空间
     当我们要直接向内存中写入内容时,这段内存空间不应该存放系统或者其它程序的数据或者代码,否则写入会导致操作系统发生错误,
DOS方式下,一般情况,0:200~0:2FF空间汇中没有存放系统或者其它程序的数据或者代码,以后我们写入内存就直接写到这段空间当中。
 
6、段前缀
     指令 mov ax,[bx]中,内存单元的偏移地址由bx给出,而段地址默认在ds中,我们可以在访问内存单元的指令中,显示的给出内存单元的段地址所在的段寄存器,比如,mov ax,ds:[bx],这里的段寄存器可以是ds,cs,es,ss,这些指令中的段寄存器在汇编语言中也被称为段前缀。
 
7、段前缀的使用
     首先我们考虑一个问题:将ffff:0~ffff:b中的数据复制到0:200~0:20b单元中。
     分析:
     (1)0:200~0:20b也就是0020:0~0020:b,它们描述的是同一个内存空间。
     (2)在循环中,源始单元 ffff:X 和目标单元 0200:X 的偏移地址X是变量,我们使用一个寄存器bx来存放
     代码如下:
 assume cs:codeseg
codeseg segment mov bx, ;偏移地址从0开始
mov cx, ;循环次数为12次 s: mov ax,0ffffh
mov ds,ax ;ds的值为0ffffh
mov dl,[bx] ;(dl)=((ds)*16+bx)将ffff:bx中的数据传入到dl中 mov ax,0020h
mov ds,ax ;ds的值为0020h
mov [bx],dl ;((ds)*16+bx)=(dl)将dl中的数据传入到0020:bx中 inc bx ;bx自增1
loop s mov ax,4c00h
int 21h codeseg ends
end
     
  当然,我们上面的代码还有需要改进的地方,从上面的代码可以看到,我们重复设置了两次ds的值,这样做没有错,只是在循环的次数比较小的情况下,一旦循环的次数增到很大时,CPU就要进行很多次重复的操作,这样效率也就比较低了。因此,我们可以对代码进行相应的改进:

 assume cs:codeseg
codeseg segment
mov ax,0ffffh
mov ds,ax ;(ds)=0ffffh mov ax,0020h
mov es,ax ;(es)=0020h mov bx, ;(bx)=0,这个时候,ds:bx指向ffff:0,es:bx指0020:0
mov cx, s:
mov dl,[bx] ;(dl)=((ds)*16+(bx)),将ffff:bx中的数据传入到dl
mov es:[bx],dl ;((es)*16+(bx))=(dl),将dl中的数据传入0020:bx inc bx
loop s mov ax,4c00h
int 21h codeseg ends
end

小甲鱼零基础汇编语言学习笔记第五章之[BX]和loop指令的更多相关文章

  1. 小甲鱼零基础汇编语言学习笔记第二章之寄存器(CPU工作原理,CPU内部通讯)

    这一章主要介绍了CPU中的重要器件——寄存器,整个系列通篇是以8086CPU作为探讨对象,其它更高级的CPU都是在此基础之上进行的升级.   1.一个典型的CPU是由运算器.控制器.寄存器等器件组成, ...

  2. 小甲鱼零基础入门学习python--课后作业

    [小甲鱼零基础入门学习python--课后作业] 小甲鱼零基础入门学习python--课后作业 本章内容: 1.基础部分的作业 2.函数部分的作业 3.字典.集合.文件部分作业 4.异常 5.Easy ...

  3. 小甲鱼零基础学python第25讲课后习题动手练习--通讯录

    小甲鱼零基础学python第25讲课后习题动手练习---通讯录 **************************通讯录要求******************************* 输入指令: ...

  4. Programming Entity Framework-dbContext 学习笔记第五章

    ### Programming Entity Framework-dbContext 学习笔记 第五章 将图表添加到Context中的方式及容易出现的错误 方法 结果 警告 Add Root 图标中的 ...

  5. [HeadFrist-HTMLCSS学习笔记]第五章认识媒体:给网页添加图像

    [HeadFrist-HTMLCSS学习笔记]第五章认识媒体:给网页添加图像 干货 JPEG.PNG.GIF有何不同 JPEG适合连续色调图像,如照片:不支持透明度:不支持动画:有损格式 PNG适合单 ...

  6. [汇编学习笔记][第五章[BX]和loop指令]

    第五章[BX]和loop指令 前言 定义描述性符号“()”来表示一个寄存器或一个内存单元的内容,比如: (ax)表示ax中的内容,(al)表示al的内容. 约定符号ideta表示常量. 5.1 [BX ...

  7. 改进我们的小游戏 - 零基础入门学习Python004

    改进我们的小游戏 让编程改变世界 Change the world by program 改进我们的小游戏 很多鱼油对改善这个游戏提出了建议,小甲鱼做了一下总结,大概有以下几个方面需要改进: 猜错的时 ...

  8. 小甲鱼零基础python课后题 P22 021函数:递归是神马

    0.递归在编程上的形式是如何表现的呢? 答:在编程上,递归表现为函数调用本身这么一个行为. 1.递归必须满足哪两个基本条件? 答:1函数调用自己. 2有正确的返回条件 2.思考一下,按照递归的特性,在 ...

  9. Python基础教程学习笔记:第一章 基础知识

    Python基础教程 第二版 学习笔记 1.python的每一个语句的后面可以添加分号也可以不添加分号:在一行有多条语句的时候,必须使用分号加以区分 2.查看Python版本号,在Dos窗口中输入“p ...

随机推荐

  1. 关于display的box和flex布局

    关于二者的区别于联系,在知乎上看到有人这么回答的 flex 2012年的语法,也将是以后标准的语法,大部分浏览器已经实现了无前缀版本. box是2009年的语法,已经过时,是需要加上对应前缀的. 另外 ...

  2. web常用的unicode字符集

    也不知道出处

  3. TB6560电机驱动器参数设置

    TB6560电机驱动器参数设置 最近接触了一些步进电机的开发,整理了一些参数设置的经验,希望能帮助到有需要的人儿~ 步进电机主要按一定的给电规律,给对应的绕组响应的电信号,电机将按一定的方向运行,而且 ...

  4. ShaderLab-12chapter屏幕后处理、图片置灰效果

    屏幕后处理的原理 使用特定的材质去渲染对应相机近裁剪平面的4边形面片(刚好填充屏幕) 亮度-Luminance公式 --扩展置灰实现 luminance = 0.2125 * Red + 0.7154 ...

  5. nginx极简教程

    Nginx 极简教程 本项目是一个 Nginx 极简教程,目的在于帮助新手快速入门 Nginx. examples 目录中的示例模拟了工作中的一些常用实战场景,并且都可以通过脚本一键式启动,让您可以快 ...

  6. 【高性能Mysql 】读书笔记(一)

    第1章 Mysql架构与历史 MYSQL最重要.最与众不同的特性是它的存储引擎架构,这种架构的设计将查询处理( Query Processing)及其他系统任务( Server Task)和数据的存储 ...

  7. someone you loved 歌词翻译

    I'm going under and this time I fear there's no one to save me 我要放弃了,这一次我怕没有人可以拯救我. This all or noth ...

  8. 谈谈IT圈的门槛与学历的关系以及如何避免青春饭?

    一.关于我自己 我是一名80后的IT老兵,从今年出现疫情后,就感觉多少有些力不从心了,因为公司的业务做的不好,公司是做普惠金融的,疫情出现后,催收逾期就非常厉害,导致公司不敢大量放贷,从而就出现了公司 ...

  9. 洛谷 P5350 序列 珂朵莉树

    题目描述 分析 操作一.二.三为珂朵莉树的基本操作,操作四.五.六稍作转化即可 不会珂朵莉树请移步至这里 求和操作 把每一段区间分别取出,暴力相加 ll qh(ll l,ll r){ it2=Spli ...

  10. react实战 : react 与 canvas

    有一个需求是这样的. 一个组件里若干个区块.区块数量不定. 区块里面是一个正六边形组件,而这个用 SVG 和 canvas 都可以.我选择 canvas. 所以就变成了在 react 中使用 canv ...