汇编笔记-王爽-汇编语言第3版-摘要

最近学习裸机,看下王爽著的<<汇编语言>>,简单笔记摘要:摘要内容来自于书中,可以简单浏览下。

第一章 基础知识
1. 汇编语言组成:
(1)汇编指令。机器码的助记符,有对应的机器码。
(2)伪指令。编译器执行,计算机并不执行。
(3)其它符号。由编译器识别,没有对应的机器码。
2. 存储单元:
(1)字节:8个bit组成一个Byte。也就是一个字节。
(2)1B=8bit, 1KB=1024B, 1MB=1024KB, 1GB=1024MB, 1TB=1024GB。
3. 总线:
(1)地址总线
(2)数据总线
(3)控制总线
4. 主板和接口卡:
5. 内存地址空间:每个物理存储器在这个逻辑存储器中占有一个地址段。

第二章 寄存器
1. 8086CPU有14个寄存器,他们分别为:AX,BX,CX,DX,SI,DI,SP,BP,IP,CS,SS,DS,ES,PSW。
2. 8086CPU所有寄存器都是16位的。
3. AX,BX,CX,DX这4个寄存器通常放一般性数据,被称位通用寄存器。
4. 8086CPU有4个段寄存器:CS,DS,SS,ES。8086CPU要访问内存时由这4个寄存器提供内存单元的段地址。
5. CS和IP是8086CPU中两个最关键的寄存器,他们指示了CPU当前要读取“指令”的地址,CS为段寄存器,IP为指令寄存器。
6. Debug工具安装和使用可以参考:

第三章 寄存器(内存访问)
1. DS寄存器通常用来存放要访问“数据”的段地址。
2. […]表示内存单元的偏移地址。
3. 指令:
(1) mov ax,1000H // 把1000H放到ax寄存器
(1) mov ds,ax // 把通用寄存器ax的内容放到段寄存器ds中。
(1) mov ax,[2] // 把数据从段寄存器:偏移地址为2的数据放到ax寄存器中。
(1) mov [2],ax // 把数据从ax寄存器传送到段寄存器:偏移地址为2地址中。
(1) sub bx,[0] // bx寄存器的数据减去段寄存器:偏移地址为0的地址的数据,结果数据送到bx寄存器中。
(1) jmp
(1) push
(1) pop
栈顶的段地址存放在SS中,偏移地址存放在SP中。
8086CPU不保证我们对栈地操作不会越界。
debug中默认所有数据都是用十六进制表示。

第四章 第一个程序
1. 汇编语言包含两种指令:
(1) 汇编指令:汇编指令是有对应地机器码地指令,可以被编译为机器指令,最终为CPU所执行。
(2) 伪指令:没有对应地机器指令,最终不会被CPU执行。伪指令是由编译器来执行的指令,编译器根据伪指令来进行相关的编译工作。
2. 伪指令:
(1)segment和ends是一对成对使用的伪指令。
(2)end:是一个汇编程序结束的标记。
(3)assume:含义为“假设”。它假设某一段寄存器和程序中的某一个用segment…ens定义的段相关联。
3. 标号:汇编源程序中,初了汇编指令,伪指令,还有标号。标号指代一个地址。
4. 源程序:源程序是由段构成的。我们可以在这些段中存放代码,数据,或者将某个段当作栈空间。
5. 程序反回:
mov ax,4c00H
int 21H
6. 编辑源程序:使用DOS下的Edit。
7. 编译:
(1)采用微软的masm.exe编译器,版本5.0。
(2)以Dos方式进入masm目录。
(3)在编译过程中,我们提供一个源程序文件输入。最多可以得到3个输出:目标文件(.obj),列表文件(.lst),交叉引用文件(.crf)。目标文件是我们最终想得到的结果,而另外两个只是中间结果,可以让编译器忽略对它们的生产。
8. 链接:
9. 程序的装载和运行:
(1)在DOS中执行.exe程序时,时正在运行的command将程序加载到内存。
(2)command设置CPU的CD:IP指向程序的第一条指令,从而使程序得以运行。
(3)程序运行结束后,返回到command中,CPU继续运行command。
10. 程序执行过程的跟踪:
(1)寄存器cx中存放的是程序的长度。
(2)寄存器ds中存放程序在内存区的段地址。例如DS的值:DS=129E。
(3)PSP:内存区前256个字节。DOS用来和程序进行通信。从256字节处向后的空间存放的是程序。例如PSP的物理地址:129E:0(根据前面DS的值推算出)。
(4)寄存器cs中执行程序的第一条指令。例如CS的值:12AE(根据前面DS的值推算出,ds值+10H,256个字节为100H)。
(5)用T命令执行程序的每一条指令,用P命令执行int 21。
(6)程序在debug中运行,那么时debug将程序加载入内存,程序运行结束返回到debug中。
(7)使用Q命令退出debug,返回到command中。

注意:
(1)使用masm编译的时候,.asm文件名称不超过8个字符(亲测,超过8个字符就提示Ubable to open input file)。
(2).asm文件的目录和debug.exe,masm.exe在同一目录。我使用的DOSBox,(我测试在其它盘符或者本盘符的其它目录也会找不到文件Ubable to open input file)。
(3)win10系统CMD控制命令下使用masm,会提示64位版本不支持16位的应用程序(没有深入研究解决办法)。所以只有在DOSBox下面编译。

第五章[BX]和loop指令
1. mov ax,[bx]解析:[bx]表示一个内存单元,它的偏移地址在bx中,段地址在ds中,这个内存单元地长度为2字节(由ax指出)。
2. 描述性符号“()”:表示一个寄存器或一个内存单元中的内容。
3. 约定符号idata表示常量。
4. inc bx 表示bx的内容+1。
5. 在汇编程序中,数据不能以字母开头,所以在写以字母开头的数据的时候,前面加0。如:mov ax,0A138H。数据A238H前面加0。
6. loop指令:
(1)第一步:(cs)=(cs)-1。
(2)第二步:判定cs中的值,不为零则转至标号处执行程序,如果为零则向下执行。
(3)cs中存放循环次数。
(4)循环功能框架:
mov cx,循环次数
s:
循环执行的程序段
loop s
7. Debug和masm编译器对指令中的[idata]却有不同的解释:
(1)Debug将[idata]解释为是一个内存单元,idata是内存单元的偏移地址。
(2)masm编译器将[idata]解释为idata。
(3)为了解决上面的问题
(a)如果用指令访问一个内存单元,则在指令中必须用[…]来表示内存单元。如:mov ax,[bx]或者mov ax,ds:[bx]。
(b)如果在[]里用一个常量idata直接给出内存单元的偏移地址,就要在[]前面显示地给出段地址所在的段寄存器。如:mov ax,ds:[0]。
8. 段前缀:用于显示地指明内存单元地段地址,ds,cs,ss,es,在汇编语言称为段前缀。

第六章 包含多个段的程序
1. dw含义是定义字型数据。dw即define world,它们所占地内存空间大小为16个字节。
2. ”end 标号“:
(1)end除了通知编译器程序结束外,还可以通知编译器程序的入口在那里。
(2)当程序被加载入内存后,加载这从程序的可执行文件的描述信息中读到程序入口地址。
(3)可以执行文件由描述信息和程序组成。
(4)程序来自于源程序中的汇编指令和定义的数据。
(5)描述信息主要是编译,连接程序对源程序中相关伪指令进行处理所得到的信息。
3. 将数据,代码,栈放入不同的段。
(1)段名相当于一个标号,它代表段地址。例如:mov ax,data。的含义就是将名称为data的段的段地址送入ax中。

第七章 更灵活的定位内存地址的方法
1. and和or指令:
(1)and指令:按位进行与运算。如:and al,00111011B。
(2)or指令:按位进行或运算。如:or al,11111110B。
2. ASCII码:“a”的ASCII码为61H,“A”的ASCII码为41H。
3. [bx+idata] 该指令也可以写成如下格式:
(1)mov ax,[200+bx]
(2)mov ax,200[bx]
(3)mov ax,[bx].200
(4)比较C语言a[i]和汇编200[bx]。可以发现,此汇编方式为高级语言提供了便利机制。
4. SI和DI指令:这两个指令和bx相近的指令,这两个指令不能分成两个8位寄存器来使用。

第八章 数据处理的两个基本问题
1. reg表示一个寄存器,用sreg表示一个段寄存器。
2. bx, si, di, bp只有这4个寄存器可以用在[…]中来进行内存单元的寻址。
(1)这4个寄存器可以单个出现。
(2)bx和si,bx和di,bp和si,bp和di,这4种组合。
(3)如在[…]中使用bp,而指令没有显示给出段地址,默认段地址在ss中。
3. 指令执行前一刻,所要处理的数据可以在3个地方:CPU内部,内存,端口。
4. 内存中的数据,可以用多种方式来给定内存单元的偏移地址:
(1)直接寻址: [idata]
(2)寄存器间接寻址: [bx]
(3)寄存器相对寻址: [bx+idata]
(4)基址变址寻址: [bx+si]
(5)相对基址变址寻址: [bx+si+idata]
5. 指令处理数据多长?
(1)通过寄存器名指明要处理的数据的尺寸。如:mov al,1。
(2)在没有寄存器名存在的情况下,用操作符X ptr指明内存单元的长度。X在汇编指令中可以为word或byte。如:mov word ptr [bx],2。
(3)有些指令默认了访问的是字单元还是字节单元。push指令只进行字操作。
6. 我们可以用[bx+idata+si]的方式来访问结构体中的数据,用bx定位整个结构体,用idata定位结构体中的某一个数据,用si定位数组项中的每个元素。汇编提供更贴切书写形式:[bx].idata[si]。
7.div指令:
(1)格式:
div reg
div 内存单元
(2)除数由8位和16位两种。
(3)如果除数是8位,被除数则为16位。被除数默认在AX中存放。商存储在AL中,余数存储在AH中。
(4)如果除数是16位,被除数则为32位。被除数在DX和AX中存放,DX存放高16位,AX存放低16位。商存储在AX中,余数存储在DX中。
8. 伪指令dd:
定义一个字节:db指令。定义一个字节:dw指令。定义双字:dd指令(double word)。
9. dup操作符:用来进行数据的重复。
如:db 3 dup (0) 表示定义3个字节,相当于db 0,0,0。
如:db 3 dup (0,1)表示定义6个字节,相当于db 0,1,0,1,0,1。
如果定义200字节的数据: db 200 dup (0)。使用dup使程序变得非常简短。

第九章 转移指令的原理
1. 操作符offset:功能是取得标号得偏移地址。
start: mov ax, offset start 取得标号start的偏移地址。
2. jmp指令:无条件转移指令。可以只修改IP,也可以同时修改CS和IP。
(2.1)段内转移:只修改IP。如jmp ax。段内转移又分短转移和近转移。CPU在执行jmp指令地时候并不需要转移的目的地址。
(a)短转移:IP修改范围:-128-127。格式:jmp short 标号。
(b)近转移:IP修改范围:-32768-32767。格式:jmp near ptr 标号。
(c)转移指令并没有告诉CPU要转移的目的地址,却告诉了CPU要转移的“位移’。
(d)
(2.2)段间转移:同时修改CS和IP:如:jmp 1000:0。 段间转移又称远转移。
(a)格式:jmp far ptr 标号。
(b)上面的汇编对应的机器码如:EA0B01BD0B,其中高地址(转移的段地址)为:BD0B,低地址(偏移地址)为:0B01。
(2.3)jmp的转移地址在不同地方:
(2.3.1)转移的地址在指令中:如:”jmp far ptr 标号”。
(2.3.2)转移的址址在寄存器中:”jmp bx”。
(2.3.3)转移的地址在内存中:
(2.3.3.1)内存单元地址的段内转移:格式:”jmp word ptr 内存单元地址”。IP=(内存单元的地址)。
(2.3.3.2)内存单元地址的段间转移:格式:”jmp dword ptr 内存单元地址”。IP=(内存单元的地址),CS=(内存单元地址+2)。
3.jcxz指令:有条件转移指令。
(3.1)格式为:”jcxz 标号“。如果(cx)=0,转移到标号处执行。
(3.2)所有的有条件转移指令都是短转移。
(3.3)对IP的修改范围都为:-128~127。
(3.4)在对应的机器码中包含转移的位移,而不是目的地址。
(3.5)(cx)!=0时,程序什么也不做,向下执行。
(3.6)类似于:if((cx)!=0)jmp short 标号。
4.loop指令:循环指令。
(4.1)格式为:”jcxz 标号“。如果(cx)=0,转移到标号处执行。
(4.2)所有的循环指令都是短转移。
(4.3)对IP的修改范围都为:-128~127。
(4.4)在对应的机器码中包含转移的位移,而不是目的地址。
(4.5)(cx)=0时,程序什么也不做,向下执行。
(4.6)类似于:
(cx)–
if((cx)!=0)jmp short 标号。

第十章 CALL和RET指令
1. ret指令:
1.(1) 用栈中数据,修改IP内容,实现近转移。
1.(2) 指令相当于:pop IP。
2. retf指令:
2.(1) 用栈中的数据,修改CS和IP的内容,实现远转移。
2.(2)指令相对于:
pop IP
pop CS
3. call指令:
3.(1) 依据位移进行转移的call指令:
3.1.(1) 指令格式:“call 标号”。近转移。
3.1.(2) 指令相当于:
push IP
jmp near ptr 标号
3.(2)转移的目的地址在指令中的call指令:
3.2.(1) 指令格式:“call far ptr 标号”。实现的是段间转移。
3.2.(2) 指令相当于:
push CS
push IP
jmp far ptr 标号
3.(3) 转移地址在寄存器中的call指令:
3.3.(1) 指令格式:“call 16位 reg”。
3.3.(2) 指令相当于:
push IP
jmp 16位 reg
3.(4)转移地址在内存中的call指令:
3.4.(1)格式1:“call word ptr 内存单元地址”。
3.4.1.(1)格式1的指令相当于:
push IP
jmp word ptr 内存单元地址
3.4.(2)格式2:“call dword ptr 内存单元地址”
3.4.2.(1)格式2的指令相当于:
push CS
push IP
jmp dword ptr 内存单元地址
4. mul指令:乘法指令。两个数相乘,要么都是8位,要么都是16位。
4.(1) 8位数相乘:
4.1.(1)一个数放在AL中,另一个数放在8位reg或者内存字节单元中。
4.1.(2)结果默认放在AX中。
4.(2)16位数相乘:
4.2.(1)一个数放在AX中,另一个数放在16位reg或者内存字单元中。
4.2.(2)结果高位默认在DX中,低位在AX中。
4.(3)指令格式1:“mul reg”。指令格式2:“mul 内存单元”。
5. 解决除发溢出问题。计算公式。

第十一章 标志寄存器
1. 标志位寄存器:PSW。
2. ZF标志:零标志位。记录相关指令执行后,其结果是否为0,如果结果为0,那么ZF=1,如果结果不为0,那么ZF=0。
2.(1) 这些运算指令影响ZF标志位:add, sub, mul, div, inc, or, and等。
2.(2) 有些指令对标志寄存器没有影响,如:mov, push, pop等,它们大都是传送指令。
3. PF标志:奇偶标志位。记录相关指令执行后,其结果的所有bit位中1的个数是否为偶数,如果1的个数为偶数,PF=1,如果为奇数,那么ZF=0。
4. SF标志:符号标志位。记录相关指令执行后,其结果是否为负。如果为负,SF=1,如果非负,SF=0。
5. CF标志:进位标志位。记录了运算结果的最高有效位向更高位的进位值,或从更高位的借位值。
6. OF标志:溢出标志位。
7. adc指令:是带进位的加法指令。它利用CF位上记录的进位值。
7.(1) 指令格式:“adc 操作对象1, 操作对象2”。实现功能:操作对象1=操作对象1+操作对象2+CF。
8. sbb指令:是带借位剑法指令。它利用CF位上记录的借位值。
8.(1) 指令格式:“sbb 操作对象1,操作对象2”。实现功能:操作对象1=操作对象1-操作对象2-CF。
9. cmp指令:比较指令。相当于减法指令。
9.(1) 指令格式:“cmp 操作数1, 操作数2”。
9.(2) 该指令并不保存结果,仅仅根据计算结果对标志寄存器进行设置。
9.(3) cmp对无符号数进行比较
9.3.(1) zf=1, 说明(ax)=(bx)
9.3.(2) zf=0, 说明(ax)!=(bx)
9.3.(3) cf=1, 说明(ax)<(bx)
9.3.(4) cf=0, 说明(ax)>=(bx)
9.3.(5) cf=0并且zf=0,说明(ax)>(bx)
9.3.(6) cf=1或者zf=1,说明(ax)<=(bx)
9.(4) cmp对有符号数进行比较,执行cmp指令后对sf和of值的对比,分析两个操作数的大小:以cmp ah,bh为利。
9.4.(1) 如果sf=1,of=0,说明实际结果为负,没有溢出。那么逻辑结果=实际结果。所以(ah)<(bh)。
9.4.(2) 如果sf=1,of=1,说明实际结果为负,有溢出。那么逻辑结果!=实际结果。下面几条是自己分析结果,不是来自课本:要使sf=1,那么差值为[80H-0FFH)之间的数。要使of=1,那么逻辑差值<-128或者>127。
9.4.2.(1) 假如逻辑差值<-128,,那么逻辑上是[0到128)的数减去[-128到0)之间某个满足条件的数,则为(80H-0FFH]减去[00H-7FH)之间的某个满足条件的数,则结果的sf=0,和条件相违背,说明逻辑差值<-128不成立。
9.4.2.(2) 假如逻辑差值>127,那么逻辑上是[0到128)的数减去[-128到0)之间某个满足条件的数,则为[00H-80H)减去[80H-0FFH)之间的某个满足条件的数,则结果的sf=1,满足条件相关值,那么说明(ah)>(bh)。
9.4.(3) 如果sf=0,of=1,说明实际结果非负,有溢出。那么逻辑结果!=实际结果。下面几条是自己分析结果,不是来自课本:要使sf=0,那么实际差值为[00H-80H)之间的数。要使of=1,那么逻辑差值<-128或者>127。
9.4.3.(1) 假如逻辑差值<-128,那么逻辑上是[0到128)的数减去[-128到0)之间某个满足条件的数,则为(80H-0FFH]减去[00H-7FH)之间的某个满足条件的数,则结果的sf=1,满足条件相关值,那么说明(ah)<(bh)。
9.4.3.(2) 假如逻辑差值>127,那么逻辑上是[0到128)的数减去[-128到0)之间某个满足条件的数,则为[00H-80H)减去[80H-0FFH)之间的某个满足条件的数,则结果的sf=1,和条件相违背,说明逻辑差值>127不成立。
9.4.(4) 如果sf=0,of=0,说明实际结果非负,没有溢出。那么逻辑结果=实际结果。所以(ah)>=(bh)。
10. 检测比较结果的条件转移指令:所有的条件转移指令的转移位移都是[-128,127]。第一个字母j表示jump。
10.(1) je指令:等于则转移。含义:equal。检测相关标志位:ZF=1。
10.(2) jne指令:不等于则转移。含义:not equal。检测相关标志位:ZF=0。
10.(3) jb指令:低于则转移。含义:below。检测相关标志位:CF=1。
10.(4) jnb指令:不低于则转移。含义:not below。检测相关标志位:CF=0。
10.(5) ja指令:高于则转移。含义:above。检测相关标志位:CF=0且ZF=1。
10.(6) jna指令:不高于则转移。含义:not above。检测相关标志位:CF=1或ZF=1。
11. DF标志:方向标志位,控制每次操作后si,di的增减。
11.(1) df=0,每次操作后si,di递增。df=1,每次操作后si,di递减。
11.(2) movesb 指令:传送一个字节,指令操作步骤:
第一步:((es)+16+(di))=((ds)+16+(si))
第二步:如果df=0则:(si)=(si)+1,(di)=(di)+1。
如果df=1则:(si)=(si)-1,(di)=(di)-1。
11.(2) movesw 指令:传送一个字,指令操作步骤类似上面。
11.(3) rep movsb格式: rep的作用是根据cx的值,重复执行后面的串传送指令。
第一步:s:movsb。
第二步:loop s。
11.(4) rep movsw格式。指令操作步骤类似上面。
12. pushf指令:将标志位寄存器的值压栈。
13. popf指令:从栈中弹出数据,送入标志寄存器中。
14. 标志位寄存器在Debug中表示:
标志/值为1的标记/值为0的标记
OF/OV/NV
SF/NG/PL
ZF/ZR/NZ
PF/PE/PO
CF/CY/NC
DF/DN/UP

第十二章 内中断
1. 内中断产生相应的中断信息:
除法错误,比如,执行div指令产生的除法溢出。中断类型码:0。
单步执行,中断类型码:1。
执行into指令,中断类型码:4。
执行int指令,提供CPU的中断类型码。
2. 中断向量表:
2.(1) CPU用中断类型码,通过查找为中断向量表,可以得到中断处理程序的入口地址。
2.(2) 对应8086机,中断向量表指定放在内存地址0处。内存0000:0000到0000:03FF的1024个单元存放着中断向量表。
2.(3) 对于8086CPU,中断向量表入口地址包括段地址和偏移地址,一个表项占两个字,高地址存放段地址,低地址存放偏移地址。
3. 中断过程:
3.(1) 取得中断类型码,N。
3.(2) 标志寄存器的值入栈,pushf。
3.(3) 设置标志寄存器的第8位TF和第9位IF的值为0。
3.(4) CS的内容入栈,push CS。
3.(5) IP的内容入栈,push IP。
3.(6))从内存地址为中断类型码*4和中断类型码*4+2的两个字单元中读取处理程序的入口地址设置IP和CS。
4. iret指令:
4.(1) iret指令相当于:
pop IP
pop CS
popf
5. 响应中断的特殊情况:CPU在执行完当前指令后,如果检测到中断信息,就响应中断,引发中断过程,可是,在有些情况下,CPU在执行完当前指令后,即使发生中断,也不会响应。如在执行完向ss寄存器传送数据的指令后,即便是发生中断,CPU也不会响应。

第十三章 int指令
1. int指令:
1.(1) 指令格式:int n。
2. int指令和iret和栈的使用
3. BIOS和DOS提供的中断
3.(1) 开机后,CPU一加电,初始化(CS)=0FFFFH, (IP)=0, 自动从FFFF:0单元开始执行程序。FFFF:0处有一条跳转指令,CPU执行该指令后,转去执行BIOS中的硬件系统检测和初始化程序。
3.(2) 对于BIOS所提供的中断例程,只需要将入口地址登记在中断向量表中,因为它们是固化到ROM中地程序,一直在内存中存在。
3.(3) 硬件系统检测和初始化完成后,调用int 19H进行操作系统的引导,从此将计算机交由操作系统控制。
3.(4) DOS启动后,除完成其它工作外,还要将它提供的中断例程装入内存,并建立响应的中断向量。
4. BIOS中断例程:
4.(1) BIOS和DOS提供中断例程,都用ah来传递内部子程序的编号。
4.(2) int 10H中断例程是BIOS提供的中断例程。
4.2.(1) ah 内部子程序编号/ al 字符/ bh 第几页/ bl颜色 / dh 行号 / dl 列号 / cx 重复个数。
4.(3) 10H中断的2子例程是置光标位置。
4.(4) 10H中断的9子例程在光标位置显示字符。
5. DOS中断例程:
5.(1) int 21H中例程是DOS提供的中断例程。
5.(2) 21H号中断例程的4ch号子程序,就我们经常在程序最后用到的,功能为程序返回,可提供返回值作为参数。
5.(3) 21H号中断例程的09h号子程序,功能为在光标位置显示字符串。
6. 应用中断例程:

第十四章 端口
1. 和CPU相连的芯片中,都有一组可以由CPU读写的寄存器。这些芯片在以下两点上相同:
1.(1) 都和CPU总线相连,当然这种连接时通过它们所在的芯片进行的。
1.(2) CPU对它们进行读或写的时候都通过控制线向它们所在的芯片发出端口读写命令。
2. CPU可以之间读写下面3个地方地数据。
2.(1) CPU内部的寄存器
2.(2) 内存单元
2.(3) 端口
3. 端口的读写指令只有两条:in和out,分别用于从端口读取数据和往端口写入数据。
3.(1) 在in和out指令中,只能使用ax和al来存放从端口中读入的数据或要发送到端口的数据,访问8位端口时用al,访问16位端口时用ax。
3.(2) 对0-255以内的端口进行读写时:
in al, 20H 从20H端口读入一个字节。
out 20H, al 往20H端口写入一个字节。
3.(3) 对256-65535的端口进行读写时,端口号放在dx中:
mov dx, 3f8h 将端口号3f8h送入dx
in al, dx 从3f8h端口读入一个字节。
out dx, al 往3f8h端口写入一个字节。
4. shl指令和shr指令:
4.(1) shl逻辑左移指令,指令的功能是:
4.1.(1) 将一个寄存器或内存单元中的数据向左移位。
4.1.(2) 将最后移出的一位写入CF中。
4.1.(3) 最低位用0补充。
4.(2) shr指令:逻辑右移指令:
4.(3) 如果移动位数大于1时,必须将移动位数放在cl中。
5. CMOS RAM芯片:简称CMOS。
5.(1) 此芯片特征:
5.1.(1)包含一个实时钟和一个128个存储单元的RAM存储器。
5.1.(2) 该芯片靠电池供电。
5.1.(3) 128个字节的RAM种,内部时实时钟占用0-0dH单元来保存时间信息,其它大部份用于保存系统配置信息,系统启动时BIOS程序读取。BIOS也提供了相关程序,我们可以配置CMOS种的信息。
5.1.(4) 该芯片有两个端口,端口地址为70H和71H,CPU通过这两个端口来读写CMOS RAM。
5.1.(5) 70H为地址端口,存放要访问地CMOS RAM单元的地址;71H为数据端口,存放从选定的CMOS RAM单元中读取的数据,或写入的数据。
5.2 在CMOS RAM中的时间
5.2.(1) 存放着年/月/日/时/分/秒。每个数字一个字节,总共14个字节。CMOS RAM中时间占用0-dH单元。
5.2.(2) 时间用BCD码表示,BCD码是以4位二进制数表示十进制数码的编码方式。
5.2.(3) BCD码值+30H=十进制数对应的ASCII码。

第十五章 外中断
1. 外中断信息:
1.(1) 可屏蔽中断:当CPU检测到可屏蔽中断信息时,如果IF=1,则CPU在执行完当前指令后响应中断,引发中断过程:如果IF=0,则不响应可屏蔽中断。
1.1.(1) 可屏蔽中断来自CPU外部,中断类型码是通过数据总线送入CPU的。
1.1.(2) 现在可解释中断过程中将IF置为0的原因了,将IF置0的原因就是,在进入中断处理程序后,禁止其它的可屏蔽中断。
1.1.(3) sti指令:设置IF=1。 cli指令,设置IF=0。
1.(2) 不可屏蔽中断:不可屏蔽中断是CPU必须响应的外中断。
1.2.(1) 不可屏蔽中断的中断类型码固定为2,所以中断过程中,不需要去中断类型码。
1.2.(2) 几乎所有由外设引发的外中断,都是可屏蔽中断。
2. PC机键盘处理过程:
2.1 键盘输入,
2.1.(1) 按下一个键,芯片产生一个扫描码,扫描码被送入主板上的相关接口芯片的寄存器中,该寄存器的端口地址为60H。
2.1.(2) 松开按键时,也产生一个扫描码,该扫描码也被送入60H端口中。
2.1.(3) 按下一个键时产生的扫描码称为通码,松开一个键的扫描码称为断码,扫描码长度为一个字节,通码第7位为0,断码第7位为1,即 断码=通码+80H。
2.1.(4) 键盘输入到达60H端口时,相关芯片就会向CPU发出中断类型码为9的可屏蔽中断信息。
3. BIOS提供了int 9中断例程,用来进行基本的键盘输入处理。
3.1 BIOS int 9中断主要工作:
3.1.(1) 读出60H端口中的扫描码。
3.1.(2) 如果时字符键的扫描码,将该扫描码和它所对应的字符码送入内存中的BIOS键盘缓冲区。如果是控制键和切换键的扫描码,则将其转变为状态字节写入内存中存储状态字节的单元。
3.1.(3) 对键盘系统进行相关控制,比如说,向相关芯片发出应答信息。
4. 指令系统总结:
4.(1) 数据传送指令:比如mov,push,pop,pushf,popf,xchg等都是数据传送指令,这些指令实现寄存器和内存,寄存器和寄存器之间的单个数据传送。
4.(2) 算术运算指令:比如add,sub,adc,sbb,inc,dec,cmp,imul,idiv,aaa等都是算术运算指令,这些指令实现寄存器和内存中的数据的算数运算。它们执行结果影响标志寄存器的sf,zf,of,cf,pf,af位。
4.(3) 逻辑指令:比如and,or,not,xor,test,shl,shr,sal,sar,rol,ror,rcl,rcr等都是逻辑指令。除了not指令外,它们的执行结果都影响标志寄存器的相关标志位。
4.(4) 转移指令:可以修改IP或者同时修改CS和IP的指令统称为转移指令。转移指令分为以下几类:
4.4.(1) 无条件转移指令,比如:jmp。
4.4.(2) 条件转移指令,比如:jcxz,je,jb,ja,jnb,jna等。
4.4.(3) 循环指令,比如loop。
4.4.(4) 过程,比如:call,ret,retf。
4.4.(5) 中断:比如:int,iret。
4.(5) 处理机控制指令:这些指令对标志寄存器或其它处理机状态进行设置,比如:cld,std,cli,sti,nop,clc,cmc,stc,hlt,wait,esc,lock等都是处理机控制指令。
4.(6) 串处理指令:这些指令对内存中的批量数据进行处理,比如:movsb,movsw,cmps,scas,lods,stos等,若要使用这些指令方便地进行批量数据的处理,则需要和rep,repe,repne等前缀指令配合使用。

第十六章 直接订址表
1. 标号:
1.(1) 地址标号:仅仅表示地址的标号,此标号在前面程序中经常用到。
1.(2) 数据标号:包含单元长度的标号,它标记了存储数据的单元的地址和长度。
1.(3) 注意:在标号后面加“:”的地址标号,只能在代码段中使用,不能再其它段中使用。
1.(4) 注意:如果想再代码段中直接用数据标号访问数据,则需要用伪指令assume将标号所在的段和一个段寄存器联系起来,否则编译器在编译的时候和,无法确定标号的段地址在哪一个寄存器中。当然这只是编译的需要,并不代表段寄存器就会真的存放该段的地址。
1.(5) “offset 标号”为获取标号的偏移地址,“seg 标号”为获取标号的段地址。
2. 直接定址表:
2.(1) 例如我们希望能够在数值0-15和字符0-F之间找到一种映射关系。这样用0-15的任何数值,都可以通过这种映射关系得到0-F中对应的字符。
2.(2) 上面映射关系的具体做法:建立一张表,表中依次存放字符0-F,这样我们可以通过0-15直接查找。
2.(3) 用查表的依据数据,直接计算出所要查找的元素在表中的位置。像这种可以通过依据数据,直接计算出所要找的元素的位置的表,我们称其为直接定址表。
3. 程序入口地址的直接定址表:
3.(1) 将功能子程序的入口地址存储在一个表中,它们在表中地位置和功能号相对应,对应关系为:功能号*2=对应的功能子程序在地址表中的偏移。

第十七章 使用BIOS进行键盘输入和磁盘读写
1. 用int 9中断例程对键盘输入处理。
2. 用int 16H中断例程读取键盘缓冲区。
3. 字符串的输入。
4. 应用int 13H中断例程对磁盘进行读写。

猜你喜欢

转载自blog.csdn.net/chentaoxie/article/details/81264613