(2011.10.26)汇编_王爽_第五章_学习小结
本章主要内容:
1. 学会如何使用loop指令;
2. 知道如何定义一个段;
3. 知道隐含段地址,显式使用段地址与偏移地址方法。
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
; 源程序名:502_loop1_循环相加.asm ; 实现功能:简单的loop循环指令1 assume cs:code ; code标号->指代地址,assume将有特定用途的段与寄存器关联起来,assume cs code segment ; 定义一个段名为code的段 segment的作用是定义段 mov ax, 0 mov cx, 236 ; 设定cx(计数寄存器)的大小[此处作用是设定循环次数] s: add ax, 123 ; 用标号s标识一个地址,从标号s开始的地址作为循环语句 loop s ; 执行 loop的循环,会分两步走,第一步是cx递减,第二步是执行s的语句 mov ax, 4c00h ; 这两条"汇编指令"所实现的功能就是程序返回程序 int 21h ; 同上,解释:即将CPU的控制权交还给使它得以运行的程序 code ends ; 段结束的"伪指令" end ; 通知编译器程序结束的伪指令
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
; 源程序名:503_loop2_循环相加.asm ; 实现功能:简单的loop循环指令2 assume cs:code code segment mov ax, 0fffh ; 在汇编程序中,数据不能以字母开头,所以要在前面加0 mov ds, ax mov bx, 6 ; 以上,设置ds:bx指向ffff:6 mov al, [bx] mov ah, 0 ; 以上,设置(al)=((ds*16)+(bx)), (ah) = 0 mov dx, 0 ; 累加寄存器清零 mov cx, 3 ; 循环3次 s: add dx, ax loop s ; 以上累加计算(ax)*3 mov ax, 4c00h int 21h ; 程序返回 code ends end
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
; 0.程序名称:505_loop和[bx]的综合应用_计算总和存放数据.asm ; 1.题目要求:计算ffff:0 ~ ffff:b 单元中的数据的和,结果存储在dx中。 ; 2.题目需注意的问题: ; 01.结果不会超出dx所存储的范围:ffff:0 ~ ffff:b内存单元中的数据是字节型数据,2的8次方,范围在0~255之间,12个这样的数据相加,结果不会大于65535,可在dx存放。 ; 02.ffff:0~ffff:b中的数据不能直接累加到dx中,ffff:0~ffff:b中的数据是8位,不能直接加到16位的寄存器dx中。 ; 03.将ffff:0~ffff:b中的8位的数据,累加到16位的寄存器dx中,有两种方法 ; 001. (dx) = (dx) + 内存中的8位数据 [问题:两个运算对象的类型不匹配] ; 002. (dl) = (dl) + 内存中的8位数据 [问题:结果有可能超界] ; 3.解决方法: ; 用一个16位的寄存器来做中介,将内存单元中的8位数据赋值到一个16位的寄存器ax中,再将ax中的数据加到dx上,从而使两个运算对象的类型匹配并且结果不会超界。 assume cs:code code segment mov ax, 0ffffh ; 上节内容,因为在汇编中,数据不能以字母开头,所以就要加个0了 mov ds, ax mov bx, 0 ; 初始化ds:bx指向ffff:0 mov dx, 0 ; 初始化累加寄存器dx, (dx) = 0 mov cx, 12 ; 初始化循环计数寄存器cx, (cx) = 12 s:mov al, [bx] mov ah, 0 add dx, ax ; 间接向dx中加上((ds)*16 + (bx) )单元中的数值 inc bx ; ds:bx指向下一单元 inc的作用是递增1 loop s mov ax, 4c00h int 21h code ends end
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
; 程序名称:508_段前缀的使用_内存单元中的数据复制1.asm ; 程序功能:将内存ffff:0~ffff:b单元中的数据复制到0:200~0:20b单元中。 ; 程序分析:0:200~0:20b单元等同于0020:0~0020:b单元,它们描述的是同一段内存空间。 ; 复制过程可用loop循环实现。 assume cs:code code segment mov bx, 0 ; 偏移地址由零开始 (bx) = 0 mov cx, 12 ; 循环12次 s: ; 在这个循环中,bl起到一个临时存储的作用,通过改变地址,先存放,再取出 mov ax, 0ffffh mov ds, ax ; (ds) = 0fffh mov dl, [bx] ; (dl) = ((ds)*16 + (bx)), 将ffff:bx中的数据送入dl mov ax, 0020h mov ds, ax ; (ds) = 0020h mov [bx],dl ; ((ds)*16+(bx))=(dl),将dl的数据送入0020:bx inc bx ; (bx) = (bx) + 1 loop s mov ax, 4c00h int 21h ; 程序返回 code ends end
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
; 程序名称:509_段前缀的使用_内存单元中的数据复制2.asm ; 程序功能:将内存ffff:0~ffff:b单元中的数据复制到0:200~0:20b单元中。 ; 程序分析:0:200~0:20b单元等同于0020:0~0020:b单元,它们描述的是同一段内存空间。 ; 复制过程可用loop循环实现。 ; 附:DOS方式下,一般情况,0:200 ~ 0:2ff这段空间中没有系统或其他程序的数据或代码,我们需要直接向一段内存中写入内容时,就使用0:200~0:2ff这段空间。 assume cs:code code segment mov ax, 0ffffh mov ds, ax mov ax, 0020h mov es, ax ; (es) = 0020h mov bx, 0 mov cx, 12 ; 循环12次 s: ; 该程序是对上一程序的循环优化程序 mov dl, [bx] ; 隐式地使用了ds这一个段地址,现在全地址是ds:[bx] mov es:[bx], dl ; ((es)*16+(bx))=(dl),将dl中的数据送入0020:bx inc bx loop s mov ax, 4c00h int 21h code ends end