汇编语言学习第五章-[BX]和loop指令

本博文系列参考自<<汇编语言>>第三版,作者:王爽

1.[bx]和内存单元的描述

[bx]与我们前面见过的[0]类似,mov ax,[0] 的意思是将内存地址为DS:0的两字节内容存入ax中。其中[0]中的0代表的是偏移地址。

类似的,我们有 mov al,[0]的意思是将内存地址为DS:0的单字节内容存入al中。那么我们可以大胆的推断mov ax,[bx]代表的是将偏移地址为bx寄存器中的值的内存地址的两字节内容存入到ax中,其段地址在DS中存储。

2.关于定义的描述性符号: "()"

后面的内容我们都将用符号"()"来表示一个内存单元或一个寄存器中的值。(ax)表示寄存器ax中的值,(al)表示寄存器al中的值。

(20000H)表示内存地址为20000的内容

((ds)*16+(bx)) ds的内容为R1,bx中的地址为R2。那么该公式代表R1*16+R2内存地址处的内容。

"( )"中可以有三种类型元素:(1).寄存器  (2)段寄存器 (3)内存地址 其表示的数据有两种类型:字和字节。如何区分数据类型是根据寄存器类型和运算类型进行区分的。

"()"的应用举例:

1.[bx]

看几个指令:

mov ax,[bx]  设偏移地址为SA,段地址默认存储在DS寄存器中,那么该指令的作用是将地址为DS:SA处的值传入ax寄存器中。

用"()"符号解释为 (ax)=((DS)*16+(bx))

mov [bx],ax  设偏移地址为SA,段地址默认存储在DS寄存器中,那么该指令的作用是将寄存器ax值传入[bx]所代表的偏移地址的位置,用"()"符号解释为 ((DS)*16+(bx))=(ax)

2. LOOP指令

LOOP指令为循环指令,其格式为 LOOP 标号,当cx不为0的时候跳转到标号处循环同时cx=cx-1,如果标号为0则向下执行。(CX默认为循环计数器)

下面实现一个小程序,用LOOP实现2^12,代码如下:

1.标号

标号s处有一条指令,add ax,ax用于累加,标号s代表该条指令的地址。

2.loop s

当cx寄存器中的值不为0的时候将跳转到标号处循环执行add ax,ax。当cx=0的时候,loop s不再跳转,将执行Loops后面的指令。

用cx和loop实现循环框架如下:

         mov cx,循环次数

标号: 代码段

        loop  标号

现在有这样一个程序功能需要实现:计算ffff:0006单元中的数乘以3,结果存放在dx中。

此程序有三个注意点

1、ffff:0006单元中的数是一个字节型数据。范围为0-255,乘以3完全可以放到dx中,不用担心超过dx的范围

2、将ffff:0006单元中的数赋值给ax,然后令(dx)=0,用dx存储累加三次的结果

3、因为ffff:0006为一个字节单元,ax为一个字单元。如何将ffff:0006单元的值赋值给ax呢。这里只需要将ax中高位字节扩展为
     00h即可,比如ffff:0006中为2CH,那么赋值给ax后为002CH,虽然数据长度不等,但是值是相等的。

注意几点,0ffffh为何前面会有个"0",当16进制数据最高位为字母的时候需要在最高位前面加上0.

下面我们通过masm和link两条指令对该程序进行编译链接生成exe文件。

用debug工具加载vpoet.exe:

DS为14E9   CS:IP为 14F9:0000 指向第一条指令 mov AX,FFFF

现在我们用U指令查看程序内容。

可以看到LOOP S处的地址为14F9:E2FC 此时LOOP S中的S标号变成地址0012,当执行了LOOP循环后,那么CX=CX-1,如果CX不为0,那么将IP设置为S标号的地址0012 CPU将执行地址14F9:0012处的指令ADD
DX,AX实现叠加。

前三条指令执行完之后,DS被设置为FFFFH,BX设置为0006H 此时DS:bx指向 FFFF:6,接下来将执行MOV AL,[BX]取出FFFF:6地址处的值,在右边显示了该值为32H

继续执行下面两条指令:

执行完后完成了对AX的复制,AX值为0032H

继续执行 MOV DX,0和MOV CX,3完成累加器和计数器的初始化

下面开始循环过程,可以看出每次循环一次CX减小1,同时DX增加一倍。

当CX=0000时候循环结束,执行接下来的返回语句 MOV AX,4c00h和int 21h。至此整个程序结束将CPU控制器交给command.

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

1.在汇编语言中,如果一个指令要访问内存单元,则在指令中必须用[...]来表示内存单元,如果在[...]中直接用常量给出内存地址的偏移地址,那么需要在"[ ]"前面加上段寄存器。比如

mov al,ds:[0]如果没有显示的给出段寄存器ds:,那么mov al,[0]在汇编语言中被理解为mov al,0

2.在汇编语言中,也可以将偏移地址存入一个普通寄存器bx,比如

mov bx,0

mov al,[bx]这样也是允许的,其中段寄存器默认在ds中

5.5  段前缀

汇编指令mov ax,[bx]将偏移地址在寄存器bx中指出,而段地址默认在ds中,我们也可以在指令中显示的给出段地址:

比如

mov ax,ds:[bx]

mov ax,ds:[bx]

mov ax,cs:[bx]

mov ax,ds:[0]

mov ax,ds:[0]

mov ax,cs:[0]

其中 ds:    cs:  ss:称为段前缀

5.6 一段安全的空间

在汇编中,当我们更改某个内存地址的内容的时候需要十分谨慎,因为该地址可能存储着重要的代码或者数据,一旦覆盖或者更改会导致整个系统的崩溃。在DOS方式下,DOS和其他合法的程序一般都不会使用0:200~0:2ff这256个字节的空间。所以,使用这段空间是安全的,我们可以在debug下查看这段地址是否为0,如果为0证明该内存段未被DOS和其他程序使用。

5.8段前缀的使用

问题,我们需要将内存ffff:0~ffff:b单元的数据复制到0:200~0:20b

分析如下:

1.0:200~0:20b等同于 0020:0~0020:b,这样描述为了使得目标地址和源地址偏移量都从0开始

2.复制过程用loop循环实现

初始化:

X=0

循环12次:

将ffff:X单元的数据送入0020:X(需要一个寄存器中转)

X=X+1

3.循环中ffff:X和0200:X的偏移量X存入bx

代码及注释如下:

OK,only stop here~~

时间: 2024-10-20 07:30:47

汇编语言学习第五章-[BX]和loop指令的相关文章

王爽《汇编语言》第三版 第五章 [BX]和loop指令

5.1 [bx] mov ax,[bx]功能:bx 中存放的数据作为一个偏移地址EA ,段地址SA 默认在ds 中,将SA:EA处的数据送入ax中. 5.2 Loop指令 指令的格式是:loop 标号,CPU 执行loop指令的时候,要进行两步操作: 1.(cx)=(cx)-1: 2.判断cx中的值,不为零则转至标号处执行程序,如果为零则向下执行. 通常我们用loop指令来实现循环功能,cx 中存放循环次数. 5.3 在Debug中跟踪用loop指令实现的循环程序 5.4 Debug和汇编编译器

汇编语言:第五章 [BX]和loop指令

1.[bx]与内存单元 [bx]是指 段地址在DS中,偏移地址在bx中的内存单元 2.loop 用于描述循环 3.我们定义的描述性符号 "()" 寄存器: (ax/al)表示ax/al寄存器中的内容 段寄存器:   ((ds)*16+(bx))表示段地址为ds内容,偏移地址为bx内容的内存单元的内容 内存单元:   (20000H)表示20000H内存单元中的内容 4.约定符号idata表示常量 mov ax,idata 表示mov ax,1 mov ax,2 等 mov ax,[id

‘第五章 [BX]和loop指令

<1>[BX] 想要完整地描述一个内存单元,需要两种信息:(1)内存单元的地址(2)内存单元的长度(类型).[BX]和[0]有些相似,表示一个内存单元,它的偏移地址在bx中.指令mov ax,[bx]的功能为将bx中存放的数据作为一个偏移地址EA,段地址SA默认在ds中,将SA:EA处的数据送入ax中,即(ax)=((ds)*16+(bx)).ps:此处的()表示的为括号内寄存器或者内存单元的内容. <2>Loop指令 loop在英语中有循环的含义,所以这个指令应该和循环有关.lo

第五章 [bx]和loop指令

要完整描述一个内存单元,需要两种信息:1.内存单元的地址:2.内存单元的长度(类型). 用[0]表示一个内存单元时,0代表单元的偏移地址,段地址默认在ds中,单元的长度(类型)可以由具体指令中的其他操作对象(比如寄存器)指出. 我们定义描述性符号:"()",为了描述上的简洁,在以后的课程中,我们将用一个描述性的符号"()"来表示一个寄存器或一个内存单元中的内容. .Loop指令 其中cx是四个通用寄存器之一. 第一次读的时候没仔细研究,执行loop s,确实是先cx

汇编语言(王爽) 第5章[BX]和loop指令

mov ax,[0] 把一个内存单元给寄存器ax,内存单元长度2个字节,偏移地址0,段地址ds mov al,[0] 把一个内存单元给寄存器al,内存单元长度1个字节,偏移地址0,段地址ds so:要描述一个内存单元,需要1.ds和偏移地址2.内存单元长度 [bx]也表示一个内存单元,偏移地址在寄存器bx中罢了 我们用()表示一个寄存器或一个内存单元中的内容 ()中可以是寄存器,段寄存器,内存单元的物理地址 5.1 [bx] mov ax,[bx] 把段寄存器ds和偏移地址在bx中的内存单元的内

汇编入门学习笔记 (四)—— [BX] 和 loop指令

疯狂的暑假学习之  汇编入门学习笔记 (四)-- [BX]  和 loop指令 参考:<汇编语言> 王爽 第5章 1.[BX] mov al,[1] 在debug中,会把bs:1 中数据赋给al,但在在masm中不会把bs:1 中数据赋给al,而是把 [1] 认为是 1 赋给al. 如果要实现在debug中的mov al,[1],在masm中就需要[bx] 如: mov bx,1 mov al,[bx] 还可以用 bs:[1] 的方式 如: mov al,bs:[1] 2.loop 循环 要使

swift学习第五章-字典的使用

//下面是关于字典的 //字典的格式[key:value] //字典可以存放基本类型和对象类型的 //声明一个字典 var dictionary1=["key1":"鸭鸭","key2":"肉包"] var keyValueCount=dictionary1.count//获取这个字典里面键值对的个数 dictionary1["key1"]="鸡鸡"//改变对应健的值 //updateV

[bx]和loop指令

1.[bx]的含义 [bx]表示一个内存单元,它的偏移地址在bx中,比如:mov ax,[bx]会将一个内存单元的内容送入ax,这个内存单元的长度是2个字节,存放一个字,偏移地址存放在bx中,段地址在ds中.mov al,[bx]则是移动半个字. 2.loop指令 loop 标号 CPU执行loop指令的时候分两步: 1.(cx)=(cx)-1 2.判定cx中的值,不为零则转至标号出执行程序,如果为0则向下执行. 从上面的描述中,我们可以看到,cx中的值影响着loop指令的执行效果.通常我们lo

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

这一章主要介绍什么是[BX]以及loop(循环)指令怎么使用,loop和[BX]又怎么样相结合,段前缀又是什么鬼,以及如何使用段前缀. 1.[BX]的概念 [BX]和[0]类似,[0]表示内存单元的偏移地址是0.要完整描述一个内存单元,需要两种信息:内存单元的地址,内存单元的长度(类型).[BX]同样也表示一个内存单元,它的偏移地址在bx中,比如指令:mov ax,[bx].这里我们以一个程序为例: 1 assume cs:codesg 2 codesg segment 3 start: mov