汇编语言(王爽)学习记录_第五章

第五章 [bx]和loop指令

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

在debug中mov ax,[0]表示将ds:0中的字型数据送入ax寄存器,而在编译器中此命令表示将0数据送入ax,则需改为mov ax,[bx]。间直接是编译器将内存单元送入ax。

完整描述一个内存单元:1.内存单元的地址2.内存单元的长度(类似al字节型,ax字型)

2.loop

loop循环的意思

3.我们定义的描述性的符号:“()”

用“( )”表示一个寄存器或一个内存单元的内容,(al)、(20000H)、((ds)*16+(bx))

比如add ax,2  描述为:(ax) = (ax)+2

(X)可表示两种数据类型:字,字节。取决于寄存器或具体的运算比如(al)表示字节型数据(ax)表示字型数据。

4.约定符号idata表示常量

例如mov ax,[idata] 可表示mov ax,[1]、mov ax,[5]。mov ax,idata可表示mov ax,1、 mov ax,3。等等

5.1 [bx]

mov ax,[bx],可以看成是:mov bx,idata  mov ax,[bx]

问题5.1

需要注意的是数据类型是字节型还是字型,其他就跟着题目看就是了。

5.2 loop指令

loop指令与cx通用寄存器有关,执行loop时要进行两步操作:1.(cx) = (cx)-1 、2.判断(cx)不为0则执行标号处程序。例:求2的12次方

assume cs:code

code segment

  mov ax,2

  mov cx,11

s:     add ax,ax

  loop s

 

  mov ax,4c00h

  int 21h

code ends

end

其中s是标号,当cx不为0时转至s处程序。

问题5.2  用加法计算123*236

assume cs:code

code segment

  mov ax,0

  mov cx,236

s:     add ax,123

  loop s

 

  mov ax,4c00h

  int 21h

code ends

end

问题5.3  上面程序循环236次可以改进程序为循环123次

assume cs:code

code segment

  mov ax,0

  mov cx,123

s:     add ax,256

  loop s

 

  mov ax,4c00h

  int 21h

code ends

end

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

 问题:计算ffff:0006单元中的数乘以3结果存储在dx中

  (1)考虑dx存储范围:ffff;0006是字节型数据0~255,乘3不会超过65535。

  (2)用哪个寄存器进行累加:先赋值给ax,在用dx累加。

  (3)ax是16位,ffff:0006单元是字节型,长度不一样如何赋值:令(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

end

注意:汇编程序中,数据不能以字母开头

debug执行情况如下:

 

将上面问题改进 将ffff:0006中的数据乘以123次:只需将(cx)=123即可,执行过程中用t一步一步太麻烦可以用g命令

当执行loop指令时不想执行123次怎么办呢?当遇到loop指令时可以用p命令

 

 

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

在以下程序

mov ax,2000

mov ds,ax

mov al,[0]

mov bl,[1]

mov cl,[2]

mov dl,[3]

debug中表现为:

  

 

 在汇编编译器中:

 

 可以看出“[idata]”在debug和汇编编译器中的不同处理,在汇编编译器中[idata]会被编译为idata值所以在汇编编译器中需要使用中间寄存器(比如bx)将idata送入“[ ]”(比如[bx])中。也可以用显示给出地址:mov  al,ds:[0]

 5.5 loop和[bx]的联合应用

计算ffff:0~ffff:b单元的数据和,结果存入dx中。

(1)是否会超出范围:((0~255)  *12)<65535不会超出范围。

(2)能否直接存入dx:内存一个单元为8位数据,dx为16位寄存器,不能。

(3) 能否将(dh)=0,(dl)=(ffff:0~b),不能会造成进位丢失。

和5.3节一样只是内存编译地址在变化每次+1.

写出程序:

 
    MOV AX,0ffffH
    MOV DS,AX
    mov bx,0
    mov dx,0
    mov cx,12
s:  mov ah,0
    mov al,[bx]
    add dx,AX
    inc bx
    loop s
编译debug查看如下:

 

 5.6 段前缀

访问内存单元时可以显示给出段地址例如:mov ax,ds:[bx]  mov ax,cs:[0]等等

5.7 一段安全的空间

在不能确定一段内存空间中是否存放着重要的数据或代码时,不能随意向其中写入数据,我试了一下结果debug卡死了。

 

 5.8 段前缀的使用

将内存ffff:0~b,单元的数据复制到0:200~20b单元中,

编写程序:

    mov AX,0ffffH
    mov ds,AX
    mov ax,20H
    mov es,ax
    mov bx,0
    mov cx,12
s:  mov al,ds:[bx]
    mov es:[bx],al
    inc bx
    loop s

 

 实验4 [bx] 和loop的使用

(1)向0:200~0:23f依次传送数据0~63

 

 (2)将上面改为9条指令,上面程序刚刚好。

(3)

  程序如下。

  1.复制的时数据,从cs :ip来

  2.cx需要用debug试出来。先使(cx)=1,用debug u命令查看指令长度

  

 

posted @ 2020-12-02 17:27  Te-mgl  阅读(231)  评论(0编辑  收藏  举报