| 
 | 
 
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册  
 
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)操作内存时要注意内存地址的表示方式 |   
 
评分
- 
查看全部评分
 
 
 
 
 
 |