(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