使用MASM用vb编写简单的程序1+2+3+……+100

6.指令要处理的数据有多长:字/字节 通过寄存器名指明数据类型/用操作符Xptr指明内存单元长度,X在汇编指令中可以为word或byte/其他方法:(没有寄存器名) :mov word ptr [1000h],2; 00 ff…;字单元

7.寻址方式的综合应用:
确定位置:起始地址和起始地址的相对地址;字符修改:确定字符在数组中的位置。
一般来说,我们可以用[bx+si+idata]的方式来访问结构体中的数据, 用bx定位整个结构体,用idata定位结构体中的某个数据项(相对地址),用si定位数组项中的每个元素。
8.DIV指令:除法:在除法算式中,除号后面的数叫做除数。
除数:有8位或16位两种,在一个寄存器reg或内存单元中。(除四个段寄存器为sreg外其他均为reg)
被除数:默认在AX或AX和DX中:如果除数为8位,被除数为16位,放在AX中;如果除数为16位,被除数为32位,高16位放在DX中,低16位放在AX中。
结果:如果除数为8位,则AL存储商,AH存储余数;如果除数为16位,则AX存储商,DX存储余数。
9. db 定义字节型数据,

第九章 转移指令的原理

1.可以修改IP或同时修改CS和IP的指令统称为转移指令。概括的讲,转移指令就是可以控制CPU执行内存中某处代码的指令。
段内转移:短转移:-128~127/近转移:-
无条件转移指令:jmp
2.操作符 offset:(编译器:取得标号的偏移地址)
3.JMP指令(无条件转移指令):转移的目的地址+转移的距离(段间转移,段内短转移,段内近转移)
不同的给出目的地址的方法,不同的转移位置,对应有不同格式的jmp指令。
(1)依据位移进行转移的jmp指令:jmp short 标号:(转移到标号处执行指令)段内短转移 IP:-128~127
CPU在执行jmp指令时并不需要转移的目的地址。
8位位移=“标号”处的地址-jmp指令下一指令第一个字节的地址
8位位移的范围:-128~127,用补码表示
8位位移由编译程序在编译时算出
(2)转移的目的地址在指令中的jmp指令:jmp far ptr 标号:段间转移(远zhaunyi) 高位段地址,低位偏移地址。

(3)转移地址在寄存器中的jmp指令:jmp 16位寄存器(reg):(IP)=(16位寄存器)

(4)转移地址在内存中的jmp指令: :*jmp word ptr 内存单元地址*(段内转移)::从内存单元地址处开始存放一个字,是转移的目的偏移地址 (IP)=(内存单元地址) :*jmp dword ptr 内存单元地址*(段间转移):从内存单元地址处开始存放两个字,高-段地址,低-偏移地址。 (CS)=(内存单元地址+2) (IP)=(内存单元地址) 相当于(cx)=(cx)– If((cx!=0)jmp short 标号; 6.dec指令:(dx)=(dx)-1 inc指令:(dx)=(dx)+1 7.根据位移进行转移的意义:方便程序段在内存中的滚动装配 8.编译器对转移位移超界的检测:“jmp 2000:10”是在debug中使用的汇编指令,汇编编译器并不认识。如果在源程序中使用,编译时也会报错。 **第十章
ret;返回到call指令的下条指令
4.MUL指令:乘法指令
一. 两个相乘的数,要么都是8位,要么都是16位。如果是8位,一个默认放在AL中,另一个放在8位寄存器或内存字节单元中。如果是16位,一个默认放在AX中,另一个放在16位寄存器或内存字单元中。
二. 结果:如果是8位乘法,结果默认放在 AX中。如果是16位乘法,结果 高位默认在DX中存放,低位在AX中存放
参数和结果传递的问题:
子程序根据提供的参数处理问题,处理后,将结果(返回值)提供给调用者。
大量:内存单元:将批量数据放在内存中,然后将它们所在内存空间的首地址放在寄存器中,传递给需要的子程序。
6.子程序的标准框架:
子程序开始:子程序使用的寄存器入栈
子程序中使用的寄存器出栈

1.标志寄存器flag:8086CPU:16位:存储的信息:程序状态字(PSW)
作用:用来存储相关指令的某些执行结果,用来对CPU执行相关指令提供行为依据,用来控制CPU的相关工作方式。
ZF标志(6):零标志位,记录相关指令执行后,结果是否为0。
注意:不影响标志寄存器的指令:push,pop,mov
PF标志(2):奇偶标志位,记录相关指令执行后,其结果的二进制中1的个数是否为偶数。如果为偶数,则pf=1;为奇数,则pf=0。
SF标志(7):符号标志位,记录相关指令执行后,结果是否为负。
如果为负,则sf=1;非负,则sf=0。
在计算机中用补码表示有符号数据:2进制8位:-128~127
注意:将结果化为2进制的16位数或8位数,看左边第一位,为0则sf=0,否则sf=1。
CF标志(0):进位标志:一般情况下,在进行无符号数运算时,它记录了运算结果的最高有效位向更高位的进位值,或向更高有效位的借位值:0~255
有进位或借位CF=1,否则CF=0。
注意:inc和loop指令不影响CF。
对位数为N的无符号数来说,其对应的二进制的最高有效位为第N-1位,而假象的第N位为更高位。
OF标志(11):溢出标志位:有溢出:of=1,否则of=0
在进行有符号数的运算时,运算结果超过了机器所能表示的范围称为溢出。
注意:有溢出/进位/借位的数要存放在OF【有符号数】/CF【无符号数】(标志寄存器)中,而不是寄存器中。
注意:二进制8位数左边第一位如果是0则不用写补码。
二进制8位数对应的十六进制:00H~FFH
DF标志(10)和串传送指令:方向标志位
cld指令:de=0:正向传送
2.adc指令:带进位加法指令,利用了CF位上记录的进位值。
格式:adc 操作对象a,操作对象b;操作对象可以是数字
sbb指令:带借位减法指令
cmp 指令:比较指令:结果保存在CPU暂存器中
做减法运算,影响标志寄存器,标志寄存器的相关位记录了比较结果:
(有/无符号数)根据ZF判断两个数是否相等。
判断逻辑上真正结果的正负与实际结果的正负,得知比较的结果:cmp ah,bh:
3.检测比较结果的条件转移指令:
转移:指它可以修改IP
条件:指它可以根据某种条件决定是否修改IP:条件转移指令的转移位移[-128~127]
条件转移指令和cmp:表示比较结果的标志位。
根据无符号数的比较结果进行条件转移的指令:CF ZF
根据有符号数的比较结果进行条件转移的指令:SF OF ZF
pushf将标志寄存器中的数据压入栈,popf从栈中弹出数据,送入标志寄存器。
5.标志寄存器在DEBUG中的表示:

cpu内部发生下面情况时,将产生相应的中断信息:
(1)除法错误:0(2)单步执行:1(3)执行int0命令:4(4)执行int命令:n
中断类型码0 1 4 n 为一个字节型数据
中断向量表就是中断处理程序入口地址的列表。保存在内存中。
对于8086中断向量表指定存在内存地址0处。从0000:0000到0000:03e8单元。共1000个字节。中断向量表中一个表项存放一个中断向量,占两个字。分别存放段地址和偏移地址。
(1)从中断信息中取得中断类型码
(2)标志寄存器的值入栈
(3)设置标志寄存器的第八位TF和第九位IF的值为0
(6)从内存地址为中断类型码*4和中断类型码*4 + 2 的两个字单元中读取中断处理程序的入口地址设置IP和CS
(1)保存用到的寄存器
(3)恢复用到的寄存器
格式:int n,n为中断类型码,功能是引发中断过程
2. int指令和iret指令配合使用与call指令和ret指令配合使用具有相似的思路。
BIOS主要包含以下内容:
(1)、硬件系统的检测和初始化程序
(2)、外部中断和内部中断的中断例程
(3)、用于对硬件设备进行I/O操作的中断例程
(4)、其他和硬件系统相关的中断例程
(1).开机后,cpu一加点,初始化(cs)= 0FFFFH,(IP)= 0,自动从FFFF:0单元开始执行程序。FFFF:0处有一条跳转指令,cpu执行该程序后,转去执行BIOS中的硬件检测和初始化程序。
(2).初始化程序将建立BIOS所支持的中断向量,即将BIOS提供的中断例程的入口登记在中断向量表中。注意,对于BIOS所提供的中断例程,只需将入口地址登记在中断向量表中即可,因为它们是固化到ROM中的内容,一直在内存中存在。
(3).硬件系统检测和初始化完成后,调用int 19h进行操作系统的引导。从此将计算机交给操作系统控制。
(4).DOS启动后,除完成其他工作外,还将它提供的中断例程装入内存,并建立相应的中断向量。
例如 我们一直在使用的4ch号子程序,即程序返回功能。

1) 1号调用——从键盘输入单个字符
功能: 等待从键盘输入一个字符并送入AL。
执行时系统将扫描键盘,等待有健按下,一旦有健按下,就将其字符的ASCII码读
入,先检查是否Ctrl-Break,若是,退出命令执行;否则将ASCII码送AL,同时将
2) 10号调用——从键盘输入字符串
功能: 从键盘接收字符串送入内存的输入缓冲区,同时送显示器显示。
调用前要求: 先定义一个输入缓冲区
MAXLEN DB 100 ;第1个字节指出缓冲区能容纳的字符个数,即缓冲区长度,不能为0
ACLEN DB ? ;第2个字节保留,以存放实际输入的字符个数
调用格式: LEA DX,MAXLEN(缓冲区首偏移地址)
1) 2号调用——在显示器上显示输出单个字符
功能:将DL中的字符送显示器显示。
【例】显示输出大写字母A
2) 9号调用——在显示器上显示输出字符串
调用格式: LEA DX,字符串首偏移地址
功能:将当前数据区中DS:DX所指向的以’ 说明:若希望显示字符串后,光标可自动回车换行,可在定义字符串时作如下更改:

在PC系统中,CPU最多可以定位64KB个不同的端口,则端口地址的范围为0~65535
端口的读写指令只有两条:in和out,分别用于从端口读写数据和往端口写入数据。
在in和out指令中,只能使用ax或al来存放从端口中读入的数据或要发送到端口中的数据。 访问8位端口时用al,访问16位端口时用ax。
对0~255以内的端口进行读写时:
对256~65535的端口进行读写时,端口号放在dx中:
2. PC机中,有一个CMOS RAM芯片,一般简称CMOS。此芯片有以下特征:
1) 包含一个实时钟和一个有128个存储单元的RAM存储器(早期的计算机为64个字节)。
2) 该芯片靠电池供电。所以,关机后期内部的实时钟仍可正常工作,RAM中的信息不丢失。
3) 128个字节的RAM中,内部实时钟占用0~0dh单元来保存时间信息,其余大部分单元用于保存系统配置信息,供系统启动时 BIOS程序读取。BIOS也提供了相关的程序,使我们可以在开机的时候配置 CMOS RAM中的系统信息。
4) 该芯片内部有两个端口,端口地址为70h和71h。CPU通过这两个端口来读写CMOS RAM
5) 70h为地址端口,存放要访问的CMOS RAM单元的地址;71h为数据端口,存放从选定的CMOS RAM单元中读取的数据,或要写入到其中的数据。
2) 从端口71h读出2号单元的内容。
shl是逻辑左移指令(*2),它的功能为:
1) 将一个寄存器或内存单元中的数据向左移位;
2) 将最后移出的一位写入CF中;
3) 最低位用0补充。
shr是逻辑右移指令(/2),它和shl所进行的操作刚好相反。
1) 将一个寄存器或内存单元中的数据向右移位;
2) 将最后移出的一位写入CF中;
3) 最高位用0补充。
如果移动位数大于1时,必须将移动位数放到cl中。如果只移动一位,则可以直接写出来。
在CMOS RAM中,存放着当前的时间:年、月、日、时、分、秒。这6个信息的长度都为1个字节,存放单元为:
秒:0 分:2 时:4 日:7 月:8 年:9
这些数据以BCD码的方式存放。BCD码是以4位二进制数表示十进制码的编码方法。
一个字节可表示两个BCD码。则CMOS RAM存储时间信息的单元中,存储了用两个BCD码表示的两位十进制数,高4位的BCD码表示十位,低4位的BCD码表示个位。

1.在PC系统中,外中断源一共有以下两类:
1) 可屏蔽中断(需要取中断类型码)
可屏蔽中断是CPU可以不响应的外中断。CPU是否响应可屏蔽中断,要看标志寄存器的IF位的设置。当CPU检测到可屏蔽中断信息时,如果I*F=1,则CPU在执行完当前指令后响应中断,引发中断过程;如果IF=0,则不响应可屏蔽中断。*
将IF置0的原因就是,在进入中断处理程序后,禁止其他的可屏蔽中断。当然,如果在中断处理程序中需要处理可屏蔽中断,可以用指令将IF置1。
2) 不可屏蔽中断:2(不需要取中断类型码)
不可屏蔽中断是CPU必须响应的外部中断。当CPU检测到不可屏蔽中断信息时,则在执行完当前指令后,立即响应,引发中断过程
2.PC机键盘的处理过程
(1)键盘中有一个芯片对键盘上的每一个键的开关状态进行扫描。按下一个键时,开关接通,该芯片就产生一个扫描码,扫描码说明了按下的键在键盘上的位置。扫描码被送入主板上的相关接口芯片的寄存器中,该寄存器的端口地址为60h。松开按下的键时,也产生一个扫描码,扫描码说明了松开的键在键盘上的位置。松开按键时产生的扫描码也被送入60h端口中。
一般将按下一个键时产生的扫描码称为通码,松开一个键产生的扫描码称为断码。扫描码长度为一个字节,通码的第7位为0,断码的第7位为1,即:断码=通码 + 80h
(2)键盘的输入到达60h端口时,相关的芯片就会向CPU发生中断类型码为9的可屏蔽中断信息。CPU检测到该中断信息后,如果IF=1,则响应中断,引发中断过程,转去执行int 9h中断例程
BIOS提供了int 9h中断例程,用来进行基本的键盘输入处理,主要的工作如下:
1) 读出60h端口中的扫描码;
2) 如果是字符键的扫描码,将该扫描码和它所对应的字符码(即ASCII码)送入内存中的BIOS键盘缓冲区;如果是控制键(如Ctrl)和切换键(如CapsLock)的扫描码,则将其转变为状态字节(用二进制位记录控制键和切换键状态的字节)写入内存中存储状态字节的单元;
3) 对键盘系统进行相关的控制,如:向相关芯片发出应答信息。
BIOS键盘缓冲区是系统启动后,BIOS用于存放int 9中断例程所接收的键盘输入的内存区。该内存区可以存储15个键盘输入,因为int 9中断例程除了接收扫描码外,还要产生和扫描对应的字符码,所以在BIOS键盘缓冲区中,一个键盘输入用一个字单元存放,高位字节存放扫描码,低位字节存放字符码。
(3) 0040:17单元存储键盘状态字节,该字节记录了控制键和切换键的状态。键盘状态字节各位记录的信息如下:
3;Alt状态,置1表示按下Alt键;
5:NumLock状态,置1表示小键盘输入的是数字;
6:CapsLock状态,置1表示输入大写字母;
7:Insert状态,置1表示处于删除态;
3. 键盘输入的处理过程:
1) 键盘产生扫描码;
2) 扫描码送入60h端口;
4) CPU执行int 9中断例程(自行设计处)处理键盘输入。

这种标号不但表示内存单元的地址,还表示了内存单元的长度,即表示在此标号处的单元,是一个字节单元,还是字单元,还是双字单元。如
使用不带“:”的标号,它们是同时描述内存地址和单元长度的标号。这种标号包含了对单元长度的描述,所以,在指令中,它可以代表一个段中的内存单元。
2. 在其他段中使用数据标号
在后面加有“:”的地址标号,只能在代码段中使用,不能再其他段中使用。
如果想在代码段中直接用数据标号访问数据,则需要用伪指令assume将标号所在的段和一个段寄存器联系起来。否则编译器在编译的时候,无法确定标号的段地址在哪一个寄存器中。
可以将标号当做数据来定义,此时,编译器将标号所表示的地址当做数据的值。
seg操作符,功能为取得某一标号的段地址。
在建立数据映射关系时,有时在数值计算方面找不到一致性的规律或者规律过于繁琐,可以使用在内存中构建表,以查表的方式来建立这种映射。
我们将通过给出的数据进行计算或比较而得到结果的问题,转化为用给出的数据作为查表的依据,通过查表得到结果的问题。具体的查表方法,是用查表的依据数据,直接计算出所要查找的元素在表中的位置。像这种可以通过依据数据,直接计算出所要找的元素的位置的表,我们称其为:直接定址表。
3. 程序入口地址的直接定址表
我们可以在直接定址表中存储子程序的地址,从而方便地实现不同子程序的调用。
用根据功能号查找地址表的方法,程序的结构清晰,便于扩充。如果加入一个新的功能子程序,那么只需要在地址表中加入它的入口地址就可以。

第十七章 使用BIOS进行键盘输入和磁盘读写

  1. int 9 中断例程对键盘输入的处理
    键盘输入将引发9号中断,BIOS提供了int9中断例程。CPU在9号中断发生后,执行int 9中断例程,从60h端口读出扫描码,并将其转化为相应的ASCII码或状态信息,存储在内存的指定空间(键盘缓冲区或状态字节)中。
    一般的键盘输入,在CPU执行完int 9中断例程后,都放到了键盘缓冲区中。键盘缓冲区中有16个字单元,可以存储15个按键的扫描码和对应的ASCII码。
  2. 使用int16h中断例程读取键盘缓冲区
    int 16h中断例程中包含的一个最重要的功能是从键盘缓冲区中读取一个键盘输入,该功能的编号为0。下面的指令从键盘缓冲区中读取一个键盘输入,并且将其从缓冲区中删除。
    1) 检测键盘缓冲区中是否有数据;
    2) 没有则继续做第1步;
    3) 读取缓冲区第一个字节单元中的键盘输入;
    4) 将读取的扫描码送入ah,ASCII码送入al;
    5) 将已读取的键盘输入从缓冲区中删除。
    BIOS的int 9中断例程和int 16h中断例程是一对相互配合的程序,int 9中断例程向键盘缓冲区中写入,int 16h中断例程从缓冲区中读出。它们写入和读出的时机不同,int 9中断例程是在有键按下的时候向键盘缓冲区中写入数据;而int 16h中断例程是在应用程序对其进行调用的时候,将数据从键盘缓冲区中读出。
    3.字符串的输入(栈的方式)
    1) 在输入的同时需要显示这个字符串;
    2) 一般在输入回车符后,字符串输入结束;
    3) 能够删除已经输入的字符。
  3. 应用int13h中断例程对磁盘进行读写
    3.5英寸软盘分为上下两面,每面有80个磁道,每个磁道又分为18个扇区,每个扇区的大小为512个字节。则:2面*80磁道*18扇区*512字节=1440KB~=1.44MB
    磁盘的实际访问由磁盘控制器进行,我们可以通过控制磁盘控制器来访问磁盘。只能以扇区为单位对磁盘进行读写。在读写扇区的时候,要给出面号、磁道号和扇区号。面号和磁道号从0开始,而扇区号从1开始。
    BIOS提供的访问磁盘的中断例程为int 13h。

我要回帖

更多关于 用vb编写简单的程序 的文章

 

随机推荐