汇编第五节-[bx]和loop指令

来源:互联网 发布:mac幼圆字体下载 编辑:程序博客网 时间:2024/05/28 16:04


第五节[BX]loop指令

[bx]:

要完整地描述一个内存单元,需要两种信息:1,内存单元的地址2,内存单元的长度(类型)

Mov ax[bx]

将一个内存单元的内容送入ax,这个内存单元的长度为2字节,存放一个字,偏移地址在bx中,段地址在ds中。

Mox al[bx]

将一个内存单元的内容送入al,这个内存单元的长度为1字节,存放一个字节,偏移地址在bx中,段地址在ds中。

Loop:循环

描述性符号():

ax)表示ax中内容。

20000H)表示内存20000H单元的内容。

((ds*16+(bx))表示ds中的ADR1作为段地址,bx中的ADR2作为偏移地址,内存ADR1ADR2单元的内容。

()中的元素可以有3种类型1.寄存器名2段寄存器名3内存单元的物理地址(一个20的数据)

x)的应用eg

Push ax 描述: (sp=sp-2;((ss*16+sp))=ax

Pop ax 描述: (ax=((ss*16+sp)) ;(sp=sp+2

x)所表示的数据两种类型1:字节,2:字

(al)(bl)(cl)得到的数据为字节型,(ax)(bx)(cx)的得到的数据为字型;

约定符号idata表示常量:

mov ax[idata]表示 mov ax[1]

Mov bxidata  表示mov bx1

Mov dsidata  不合法

 

1. [BX]

Mov ax,[bx]

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

Mov [bx],ax

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

 

Mov bx,1

Inc bx

执行后,bx=2.

 

2. Loop指令:

Loop指令的格式:loop标号 ,CPU执行loop指令的时候,要进行两步操作

1(cx)=(cx)-1

2,判断cx中的值,不为0则转至标号处执行程序,如果为0就向下执行。

用加法完成123*236结果存在ax中。

assume cscode

code segment

mov ax,0

mov cx,236

  s:add ax,123

    loop s

mov ax,4c00h

int 21h

code ends

End

 

3. Debug中跟踪用loop指令实现的循环程序

ffff:0006单元中的数乘以3,结果存在dx

将此单元中的数赋值给ax,用dx进行累加。

实现到ax的赋值,应当令(ah)=0,(al)=(ffff6H)

assume cs:code

code segment

mov ax,0ffffh

mov ds,ax

mov bx,6

mov al,[bx]

mov ah,0

mov dx,0

mov cx,3

  s:add dx,ax

loop s

mov ax,4c00h

int 21h

code ends

ends

在汇编源程序中,数据不能以字母开头所以要在前面家加0

eg9138h在汇编中可以直接写9138h,而A00h写为0A000h

(遇到int 21要用p命令执行)

如果要一次在debug中执行完标号s前的指令,可以用-gIP

4. Debug和汇编编辑器masm对指令的不同处理:

Debug中指令 mov ax[0]表示将ds0处的数据送入ax中。但是在汇编程序中,指令”mov ax,[0]”被编译器当作指令mov ax0处理

编译器将”[idata]”是一个内存单元,”idata”是内存单元的偏移地址;而编译器将”idata”解释为”idata”

 

如何在源程序中实现将内存2000020001单元中的数据送入albl中。

借助bx寄存器

Mov ax2000h

Mov dsax

Mov bx0

Mov al[bx]

也可以显式给出段地址所在的段寄存器。 mov al,ds:[0]

汇编程序中以下指令的含义:

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]相同

 

总结:

1. 在汇编源程序中,如果用指令访问一个内存单元,则在指令中,必须用[...]来表示内存单元,如果在[]里用一个常量idata直接给出内存单元的偏移地址,就要在[]前面显式给出段地址所在的段寄存器。Eg :mov al,ds:[0] 没有ds显式 编译器masm将指令中[idata]解释为idata

2. 如果在[]里用寄存器,比如bx,间接给出内存单元的偏移地址,则段地址默认在ds中,显式不显式给出段寄存器都可以

 

5. loop[bx]的联合应用

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

1. 不会超界 2.不能将8位直接加到16bx

assume cs:code

code segment

mov ax,0ffffh

mov ds,ax

mov bx,0

mov dx,0

mov cx,12

  s:mov al,[bx]

mov ah,0

add ax,ax

inc bx

loop s

mov ax,4c00h

int 21h

code ends

end

 

6. 段前缀:

mov ax,ds:[bx]

mov ax,cs:[bx]

mov ax,ss:[bx]

用于显式得指明内存单元的段地址的”ds:” “cs:””ss:””es:”,在汇编语言中称为段前缀

 

7. 一段安全的空间:

8086模式中,随意向一段内存空间写入内容很危险,因为这段空间中可能存放着重要的系统数据或者代码。

在一般PC机中,DOS方式中,DOS和其他合法的程序一般都不会使用0200~02ff256字节的空间

 

8. 段前缀的使用:

将内存ffff:0~ffff:b单元中的数据复制到0200~020b单元中

assume cscode

code segment

mov ax,0ffffh

mov ds,ax

mov ax,0020h

mov es,ax

mov bx,0

mov cx,12

  s:mov dl,[bx] ffffbx中的数据送入dl

mov es:[bx],dl dl中的数据送入0020bx

inc bx

loop s

mov ax,4c00h

int 21h

code ends

end

文本转语音功能仅限200个字符
选项 :历史 :反馈 :Donate关闭
原创粉丝点击