鱼C论坛

 找回密码
 立即注册
查看: 2440|回复: 0

[学习笔记] 《汇编语言》第五章

[复制链接]
发表于 2017-7-19 16:06:44 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

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则向下执行

如:
  1. assume cs : code
  2. code segment
  3.         mov ax, 2H
  4.         mov cx, 11
  5.   s:add ax, ax
  6.     loop s
  7.        
  8.         mov ax, 4c00H
  9.         int 21H
  10. code ends
  11. end
复制代码


进行2的12次方的计算,把结果放在ax中
循环的过程:
1.png
2.png

可见
(1)循环的次数放在cx中
(2)loop 标号要在循环程序段后面
(3)要循环的程序要在标号和loop 标号之间
框架如下:

标号:
        循环程序
        loop 标号

5.3节 在debug中跟踪loop指令实现的循环程序
问题:计算FFFF: 6单元的数据乘以3,结果存在dx中
答案:
  1. assume cs : code
  2. code segment
  3.         mov ax, 0ffffH
  4.         mov ds, ax
  5.         mov bx, 6
  6.         mov al, [bx]
  7.         mov ah, 0
  8.         mov dx, 0
  9.         mov cx, 3
  10.        
  11.   s:add dx, ax
  12.         loop s
  13.        
  14.         mov ax, 4c00H
  15.         int 21H
  16.        
  17. code ends
  18. end
复制代码

注意到mov ax, 0ffffH,FFFFH地址要这样写0FFFFH,因为在汇编程序中,数据不能以字母开头。如:“9138H”在汇编程序中可以直接写为:“9135H”,而“A000H”在汇编程序中要写为“0A000H”
下面我们对该程序进行跟踪:
3.png
看到程序在CS: IP中,用U命令查看到对应的机器指令
4.png
这是执行了前三条指令的图示
可知道FFFF6的内存的数据是32H
5.png
上图的指令完成了对dx和cx的初始化和设置循环次数
6.png
当执行了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为止,如下图
7.png

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)汇编程序实现
  1. assume cs :code
  2. code segment
  3.         mov ax, 2000H
  4.         mov ds, ax
  5.         mov al, [0]
  6.         mov bl, [1]
  7.         mov cl, [2]
  8.         mov dl, [3]
  9.        
  10.         mov ax, 4c00H
  11.         int 21H
  12. code ends
  13. end
  14.        
  15.        
复制代码

(1)中在debug中的情况
9.png

(2)在debug中的情况
8.png

从中可以看出debug和masm编译器对形如:mov al,【0】,mov bl,【1】这类指令在解释上的不同,debug将他解释为【idata】是一个内存单元,而编译器将【idata】解释一个常量
那么如何解决子啊编译器中表示内存单元呢?
比如我们可以这样做
  1. mov ax, 2000H
  2.         mov ds, ax
  3.         mov bx, 0
  4.         mov al, [bx]
复制代码

可是这样比较繁琐
我们用另一种方法,在内存单元之前显式的给出段地址所在的段寄存器,如:
  1. mov ax, 2000H
  2.         mov ds, ax
  3.         mov al, ds:[0]
复制代码


比较一下汇编程序中一下指令的含义:
10.png

5.5节 loop和【BX】的联合应用
问题:计算FFFF:0~FFFF:b单元中的数据和,结果存放在dx中
答案:
  1. assume cs :code
  2. code segment
  3.         mov ax, 0ffffH
  4.         mov ds, ax
  5.         mov bx, 0
  6.         mov dx, 0
  7.         mov cx, 12h
  8.        
  9.   S:mov al,[bx]
  10.     mov ah, 0
  11.         add dx, ax
  12.         inc bx
  13.         loop s
  14.        
  15.         mov ax, 4c00H
  16.         int 21H
  17. code ends
  18. end
  19.        
  20.        
复制代码

本质就是:找到所在的存储单元的地址,然后将该地址的内容方在一个通用寄存器中,然后将另一个寄存器置0,然后让两个寄存器相加。

5.6 节 段前缀
  1. mov ax, ds:[bx]
  2. mov ax, es:[bx]
  3. mov ax, es:[bx]
  4. mov ax, ss:[0]
复制代码

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

5.7节 一段安全的空间
  1. mov ax, 1000H
  2. mov ds, ax
  3. mov al, 0
  4. 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单元中
答案:
  1. assume cs : code
  2. code segment
  3.         mov ax, 0ffffH
  4.         mov ds, ax
  5.        
  6.         mov bx, 20H
  7.         mov es. ax
  8.        
  9.         mov bx, 0
  10.         mov cx, 12
  11.        
  12.   s:mov al, [bx]
  13.     mov es:[bx], al
  14.         inc bx
  15.         loop s
  16.        
  17.         mov ax, 4c00H
  18.         int 21H
  19.        
  20. code ends
  21. 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)操作内存时要注意内存地址的表示方式

评分

参与人数 1鱼币 +8 收起 理由
小甲鱼 + 8 支持楼主!

查看全部评分

本帖被以下淘专辑推荐:

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-20 04:24

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表