|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
1、[bx]表示内存单元,段地址在ds,偏移地址在bx寄存器中
2、loop 在汇编指令中表示循环
3、()表示()里面的内容,即里面的数据。可以(寄存器)、(段寄存器)和(内存单元的物理地址)
4、idata 表示常量
5.1节 【BX】
mov ax, [bx]
功能:把在段地址为(ds),偏移地址为(bx)的内存单元的内存送入ax中,即((ds) * 16 + (bx)) = (ax)
反之亦然
inc bx
功能:(bx) + 1 ,和add bx, 1差不多
5.2节 loop指令
loop 格式:loop 标号,要执行loop指令要执行这两步操作
1、(cx) = (cx) - 1
2、判断cx中的值,不为0则转至标号处继续执行程序,如果为0则向下执行
如:assume cs : code
code segment
mov ax, 2H
mov cx, 11
s:add ax, ax
loop s
mov ax, 4c00H
int 21H
code ends
end
进行2的12次方的计算,把结果放在ax中
循环的过程:
可见
(1)循环的次数放在cx中
(2)loop 标号要在循环程序段后面
(3)要循环的程序要在标号和loop 标号之间
框架如下:
标号:
循环程序
loop 标号
5.3节 在debug中跟踪loop指令实现的循环程序
问题:计算FFFF: 6单元的数据乘以3,结果存在dx中
答案: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
注意到mov ax, 0ffffH,FFFFH地址要这样写0FFFFH,因为在汇编程序中,数据不能以字母开头。如:“9138H”在汇编程序中可以直接写为:“9135H”,而“A000H”在汇编程序中要写为“0A000H”
下面我们对该程序进行跟踪:
看到程序在CS: IP中,用U命令查看到对应的机器指令
这是执行了前三条指令的图示
可知道FFFF6的内存的数据是32H
上图的指令完成了对dx和cx的初始化和设置循环次数
当执行了add dx,ax之后,(IP) = 0014H,即CS: IP 指令14bc: 14处的指令,接着执行“loop s”的指令,第一步,先将(CS) - 1,(CS) = 2,第二步,因为(CS)不等于0,将IP设置为0012,即CS:IP指向14bc:12的地址,执行add dx, ax。接着将重复“add dx,ax“和”loop 0012“直到CX = 0为止,如下图
5.4节 Debug和汇编编译器masm对指令的不同处理
(1)在debug中编程实现
mov ax, 2000
mov ds, ax
mov al, [0]
mov bl, [1]
mov cl, [2]
mov dl, [3]
(2)汇编程序实现assume cs :code
code segment
mov ax, 2000H
mov ds, ax
mov al, [0]
mov bl, [1]
mov cl, [2]
mov dl, [3]
mov ax, 4c00H
int 21H
code ends
end
(1)中在debug中的情况
(2)在debug中的情况
从中可以看出debug和masm编译器对形如:mov al,【0】,mov bl,【1】这类指令在解释上的不同,debug将他解释为【idata】是一个内存单元,而编译器将【idata】解释一个常量
那么如何解决子啊编译器中表示内存单元呢?
比如我们可以这样做mov ax, 2000H
mov ds, ax
mov bx, 0
mov al, [bx]
可是这样比较繁琐
我们用另一种方法,在内存单元之前显式的给出段地址所在的段寄存器,如:mov ax, 2000H
mov ds, ax
mov al, ds:[0]
比较一下汇编程序中一下指令的含义:
5.5节 loop和【BX】的联合应用
问题:计算FFFF:0~FFFF:b单元中的数据和,结果存放在dx中
答案:assume cs :code
code segment
mov ax, 0ffffH
mov ds, ax
mov bx, 0
mov dx, 0
mov cx, 12h
S:mov al,[bx]
mov ah, 0
add dx, ax
inc bx
loop s
mov ax, 4c00H
int 21H
code ends
end
本质就是:找到所在的存储单元的地址,然后将该地址的内容方在一个通用寄存器中,然后将另一个寄存器置0,然后让两个寄存器相加。
5.6 节 段前缀mov ax, ds:[bx]
mov ax, es:[bx]
mov ax, es:[bx]
mov ax, ss:[0]
用以显式的指明内存单元的段地址:”es“,”ds“,”cs“,”ss“,在汇编语言中称为段前缀
5.7节 一段安全的空间mov ax, 1000H
mov ds, ax
mov al, 0
mov ds:[0], al
这样的做法是危险的,因为我们不知道10000H这个内存中有没有存放其他指令,如果10000H中存放一些重要的系统数据和代码,”mov ds:[0], a“将引发错误。
5.7节的总结:
(1)我们需要向一段内存写入内容;
(2)这段内存空间不应存放其他数据和代码;
(3)DOS方式下,一般情况,0:200~0:2FF空间没有其他系统或其他程序的数据或代码;
(4)以后在写入内存数据和代码的时候,用0:200~0:2FF这段空间。
5.8节 段前缀的使用
问题:将内存FFFF:0~FFFF:b单元中的数据复制到0:200~0:20b单元中
答案:assume cs : code
code segment
mov ax, 0ffffH
mov ds, ax
mov bx, 20H
mov es. ax
mov bx, 0
mov cx, 12
s:mov al, [bx]
mov es:[bx], al
inc bx
loop s
mov ax, 4c00H
int 21H
code ends
end
思路:找到双方的内存单元地址,然后将一方的内容放在一个寄存器中,然后将寄存器的内容放在所最终要放在的内存单元中,偏移地址用循环来自增。
总结:
(1)【BX】也是表示内存单元,偏移地址在BX寄存器中的数据
(2)loop 标号 功能是循环,循环次数放在cx中,第一步(CX) - 1 = (CX),判断(CX)是否为0,不为0则执行标号:之后的指令
(3)在汇编程序中mov ax , [0]表示将0放在ax寄存器中,[0]要表示内存单元要mov ax, ds:[0]或,mov ax, [bx],[bx]段地址在ds中。
(4)mov ax, ds:[0]中的ds是段前缀
(5)操作内存时要注意内存地址的表示方式 |
评分
-
查看全部评分
|