汇编语言学习——第五章 [BX] 和LOOP 指令
来源:互联网 发布:交大网络教育学院登录 编辑:程序博客网 时间:2024/05/22 01:56
1、关于[BX]
[BX]用来表示一个内存单元的偏移地址,段地址默认在DS中取得。
一条简单指令的功能:
mov ax,[bx]
功能:bx 中存放的数据作为一个偏移地址EA ,段地址SA 默认在DS 中,将SA:EA处的数据送入ax中。
即: (ax)=(ds *16 +(bx));
2、 LOOP指令
指令的格式是:loop 标号,CPU 执行loop指令的时候,要进行两步操作:
① (cx)=(cx)-1;
② 判断cx中的值,不为零则转至标号处执行程序,如果为零则向下执行。
CX中的值影响着loop指令的执行结果,CX 中存放循环次数。
编程计算2^12
ASSUME CS:CODESG
CODESG SEGMENT
START:
MOV AX,2
MOV CS, 11
S: ADD AX, AX
LOOP S
MOV AX, 4C00H ; 程序的返回。
INT 21H
CODESG ENDS
END START
程序分析:
(1)标号
在汇编语言中,标号代表一个地址,此程序中有一个标号s 。
它实际上标识了一个地址,这个地址处有一条指令:add ax,ax。
(2)loop s
CPU 执行loop s的时候,要进行两步操作:
① (cx)=(cx)-1;
② 判断cx 中的值,不为0 则转至标号s 所标识的地址处执行(这里的指令是“add ax,ax),
如果为零则执行下一条指令(下一条指令是mov ax,4c00h)。
我们可以利用cx来控制add ax,ax的执行次数。
用cx和loop 指令相配合实现循环功能的三个要点:
(1)在cx中存放循环次数;
(2)loop 指令中的标号所标识地址要在前面;
(3)要循环执行的程序段,要写在标号和loop 指令的中间。
用cx和loop指令相配合实现循环功能的程序框架如下:
mov cx,循环次数
s:
循环执行的程序段
loop s
3、编程问题。
计算ffff:0006单元中的数乘以3,结果存储在dx中。程序如下:
ASSUME CS:ABC
ABC SEGMENT
START:
MOV AX, 0FFFFH
MOV DS, AX
MOV BX, 0006H
MOV AH, 0
MOV AL, [BX]
MOV DX, 0
MOV CX, 3
S:
ADD DX, AX
LOOP S
MOV AX, 4C00H
INT 21H
ABC ENDS
END START
分析:
注意程序中的第一条指令mov ax,0ffffh。
我们知道大于9FFFH的十六进制数据A000H、A001H、…… 、C000H、C001H等,
在书写的时候都是以字母开头的。
而在汇编源程序中,数据不能以字母开头,所以要在前面加0。
注:在调试LOOP指令时,可以用G命令或P命令跳过循环。
4、Debug和汇编编译器MASM的不同
1)在Debug中,输入的数值,默认是16进制,而在源程序中,默认是10进制,表示16进制要加‘H'
2)偏移地址的表示不同。
在Debug中,要将ds:0处的数据送入al中。指令是 MOV AL,[0]
在汇编源程序中,指令是 MOV BX, 0 MOV AL,[BX]
如果直接 mov ax,[0] ,那么将被编译器当作指令 “mov ax,0” 处理。
在MASM中mov ax, [2]是解释为mov ax,2的。一般我们是通过BX来代替,
先 mov bx, 2 再通过mov ax, [bx]来实现。
如果要像DEBUG一样直接用[2]的话,那么一定要加上段地址! MOV AX,DS:[0],段前缀
5、loop和[bx]的联合应用
计算ffff:0~ffff:b单元中的数据的和,结果存储在dx中。
分析:
1)运算后的结果是否会超出 dx 所能存储的范围?
ffff:0~ffff:b内存单元中的数据是字节型数据,范围在0~255之间,12个这样的数据相加,结果不会大于 65535 ,可以在dx中存放下
2)我们是否将 ffff:0~ffff:b中的数据直接累加到dx中?
当然不行,因为ffff:0~ffff:b中的数据是8位的,不能直接加到16位寄存器dx中。
3)我们能否将ffff:0~ffff:b中的数据累加到dl中,并设置(dh)=0,从而实现累加到dx中的目标?
这也不行,因为dl是8位寄存器,能容纳的数据的范围在小 255 之间,ffff : 0~ffff:b中的数据也都是 8 位,如果仅向dl中累加12个 8 位数据,很有可能造成进位丢失。
解决的一种思路是:用一个16位寄存器来做中介。
我们将内存单元中的 8 位数据赋值到一个16位寄存器ax中,再将ax中的数据加到dx上,从而使两个运算对象的类型匹配并且结果不会超界。
汇编代码如下:
ASSUME CS:CODESG
CODESG SEGMENT
START:
MOV AX, 0FFFFH ; 一定要加上0
MOV DS, AX
MOV BX, 0
MOV CX, 12 ; 循环的次数是12次
MOV DX, 0
S:
MOV AL, [BX]
MOV AH, 0
ADD DX, AX
INC BX ; 指向下一个字节单元。
LOOP S
MOV AX, 4C00H
INT 21H
CODESG ENDS
END START
6、一段安全的空间
在8086模式中,随意向一段内存空间写入内容是很危险的 ,因为这段空间中可能存放着重要的系统数据或代码。
为了避免冲突,我们需要有一段内存空间可以供我们编程使用。
在一般的PC机中,DOS方式下,DOS和其他合法的程序一般都不会使用0:200~0:2FF( 0:200h~0:2FFh)的256 个字节的空间。
所以,我们使用这段空间是安全的。
为什么DOS和其他合法的程序一般都不会使用0:200~0:2FF这段空间?暂时不明白,接下来的学习可能会讲解到这个问题。
由于在DOS方式下,一般情况, 0:200~0:2FF 空间中没有系统或其他程序的数据或代码;
所以我们需要直接向一段内存中写入内容时,就使用0:200~0:2FF这段空间。
7、另外一个编程题
将内存ffff:0~ffff:b段元中的数据拷贝到 0:200~0:20b单元中。
代码一:
ASSUME CS:CODESG
CODESG SEGMENT
START:
MOV BX, 0 ; 偏移地址
MOV CX, 12 ; 确定循环的次数
S: MOV AX, 0FFFFH;
MOV DS, AX
MOV DL, [BX] ; // 因为是字节单元,8位,所以是 DL
MOV AX, 0020H
MOV DS, AX
MOV [BX],DL ;
INC BX ; BX自增一,指向下一个字节单元
LOOP S
MOV AX, 4C00H ; 程序返回。
INT 21H
CODESG ENDS
END START
使用两个寄存器进行改进。
ASSUME CS:CODESG
CODESG SEGMENT
START:
MOV BX,0
MOV CX,12
MOV AX,0FFFFH
MOV DS,AX
MOV AX, 0020H
MOV ES, AX ; 这里多了一个段寄存器ES
S: MOV DL,[BX]
MOV ES:[BX],DL ; 这里显示地指出了地址 ES:[BX]
INC BX
LOOP S
MOV AX, 4C00H
INT 21H
CODESG ENDS
END START
个人总结: 我觉得本章的重点主要是[bx]的理解,loop的熟悉和运用,区分Debug命令和汇编源程序的不同,
以及对一段安全空间的认识。
- 汇编语言学习——第五章 [BX] 和LOOP 指令
- 汇编语言学习第五章-[BX]和loop指令
- 王爽《汇编语言》(第二版) 学习笔记 (第五章 [BX]和loop指令 )
- 王爽《汇编语言》(第二版) 学习笔记 (第五章 [BX]和loop指令 )
- 汇编语言04——[BX]和loop指令
- 汇编语言-[BX]和loop指令
- [汇编学习笔记][第五章[BX]和loop指令]
- 第五章 [bx]和loop指令
- 《汇编语言》第二版 王爽著 第五章 [BX]和loop指令 要点
- 汇编语言学习笔记(5)——[bx]和loop
- <学习笔记>王爽汇编语言__[BX]和loop指令
- 汇编语言学习笔记(五)bx和loop指令
- 王爽汇编第五章作业 [BX]和LOOP指令
- 《汇编语言(王爽)》第五章([bx]和loop指令)、第六章(包含多个段的程序)【总结】
- [bx]和loop指令
- [bx]和loop指令
- [bx]和loop指令
- [bx]和loop指令
- hdu 4674 边双连通缩点+倍增lca+麻烦的讨论 (2013多校联合)
- 分析集线器的工作原理--视频学习笔记
- VC中自定义消息的方法及步骤
- MultiByteToWideChar和WideCharToMultiByte的用法
- easyui中关闭所有的tab标签
- 汇编语言学习——第五章 [BX] 和LOOP 指令
- C语言实现函数模板
- hdu1128 Self Numbers
- linux注册设备驱动的理解
- Linux文件系统十问
- QXL驱动分析(二)——FindAdapter
- WAIT TYPE:PAGEIOLATCH_SH
- Thinking in Java [Java编程机制] 学习笔记 -- Priority Queue
- js 验证 商品货号并批量生成