汇编前十三章汇总(复习用)

第二章 寄存器

cpu的主要的部件是寄存器, 不同的cpu,寄存器的个数、结构是不相同的。
在8086cpu中有14个寄存器,这些寄存器是:AX、BX、CX、DX、SI、DI、SP、BP、IP、CS、SS、DS、ES、PSW。

  1. IP:指令指针,指向当前相互要取出的指令字节,当BIU从内存中取出一个指令后,IP就自动加1,这里的1指的不是一个字节,而是该条指令所占的字节数。 IP指向的是指令地址的段内地址偏移量,又称为偏移地址(Offset Address)或者有效地址(A, Effective Address)。
  2. CS:代码段寄存器
  3. DS:数据段寄存器
  4. SS:堆栈寄存器
  5. ES:附加段寄存器

其他的寄存器会在后面相应的章节一一列出作用。

2.1 通用寄存器

8086CPU的所有寄存器都是16位的,可以存放俩个字节。
其中通用寄存器为AX、BX、CX、DX这四个。
这四个寄存器又可以分为8个单独的寄存器来使用,拿AX来说,可以分为高低俩个字节,名字分别为AH、AL。
虽说这四个寄存器都是通用寄存器,但是其都有独自的功能和特点。

  1. AX:累加寄存器,通常用于运算,在乘除指令中指定用来存放操作数,另外,所有的I/O指令都使用这一寄存器与外界设备传输数据。
  2. BX:基址寄存器,常用于地址索引。
  3. CX:计数寄存器,常用于计数;常用于保存计算值,如位移指令,循环(loop)和串处理指令中作隐含的计数器。
  4. DX:数据寄存器,常用于数据传递。

2.2 字在寄存器中的存储

分为俩种

  1. 字节:记为byte,一个字节由8个bit组成,可以存在8位寄存器中,如AL
  2. 字:记为word,一个字由俩个字节组成,分别成为高位字节和低位字节,可以存在16位寄存器中,如AX。

2.3 几条汇编指令

2.4 物理地址

所有的内存单元构成的存储空间是一个以为的线性空间,每一个内存单元在这个空间中都有一个唯一的地址,这个地址就称为物理地址。

2.5 16位结构的CPU

16位结构或者说(16位机,机器字长位16位等)描述了CPU具有的结构特性为

  1. 运算器ALU一次最多可以处理16为的数据;
  2. 寄存器的最大宽度为16为;
  3. 寄存器和运算器之间的通路为16位;

2.6 8086CPU的物理寻址方法

物理地址由地址加法器算出
物理地址=段地址*16+偏移地址
更一般的说 物理地址=基础地址+偏移地址
其中基础地质 = 段地址*16

2.8 段的概念

其实在内存中,并没有所谓的分段,但是我们可以用分段的方式来管理内存。
我们可以认为:比如说 地址10000H ~ 100FFH的内存单元构成一个段,段的起始地址(基础地址)为10000H,段地址为1000H,大小为100H。也可以将该段分为俩个段,如10000H ~ 1007FH 和 10080H ~ 100FFH。起始地址分别为1000H 和 1008H。

值得注意的是:段地址*16一定是16的倍数,所以一个段的起始地址一定是16的整数倍;偏移地址为16位,16位地址的寻址能力为64KB,所以一个段的最大长度为64KB。

2.9 段寄存器

8086CPU的段寄存器有四个:CS、DS、SS、ES。

2.10 CS和IP

CS和IP分别为代码段寄存器和指令指针寄存器。
CPU读取指令的过程可以概括为一下的过程
(1)从CS:IP指向的内存单元读取指令,读取的指令进入指令缓冲区。
(2)IP=IP+所读取指令的长度,从而指向下一条指令。
(3)执行指令。转到第一个步骤,重复过程。

2.11 修改CS、IP(jmp指令)

不能通过mov指令来设置CS和IP的值。
修改CS、IP的值的指令中有一个:jmp指令。

  1. 如果想同时修改CS、IP的值,可以用“jmp 段地址: 偏移地址”来完成。如
    jmp 2AE3:3,执行完,CS=2AE3H,IP为0003H,CPU从2AE33H处读取指令。

  2. 若只想修改IP,可以用“jmp 一个合法寄存器”来完成,如
    mov ax,1000H jmp ax 执行后 IP = 1000H。

第三章 寄存器(内存访问)

3.1 内存中字的存储

CPU中,用16位寄存器来存储一个字。高8位存放高位字节,低8位存放低位字节。在内存存储中,内存单元式字节单元,那么一个字就需要用俩哥哥地址连续的内存单元来存放,这个字的低位字节存放在低地址单元中,高位字节存放在高地址单元中。这叫小端方式,还有另外一个存放的方式大端方式。
这里就涉及到存储器中数据的组织方式了:

  1. 大端方式‘
    高位字节排放在内存的低地址端,低位字节存放在高地址端

  2. 小端方式
    低位字节存放在内存的低地址端,高位字节存放在高地址端

8086CPU采用的是X86结构,采用小端方式。

然后在读或写一个内存单元里面的数据的时候,需要指定起始地址,读取的长度。读取的长度是一个字还是一个字节。小端方式的起始地址是低地址。
如使用一个立即数ds:[0],这里就要指定 是字还是字节,字节:byte ptr ds:[0],字:word ptr ds:[0]

3.2 DS和[address]

CPU在读写一个内存单元的时候需要给出该内存单元的地址,内存地址由段地址和偏移地址组成。
DS:用来存放数据的段地址
SS:用来存放栈的段地址
CS:用来存放代码的段地址
这里用DS来举例,比如说我们现在要读取10000H单元的内容,段地址为1000H,偏移地址为0H。那么就要用一下的代码来实现。
mov bx,1000H
mov ds,bx
mov al,[0]
像DS这样的段寄存器,不能直接将一个立即数直接MOV到DS中,并且在访问内存单元的时候,必须指定DS以后,通过mov 通用寄存器,[偏移地址]来实现。

将一个数送入内存单元也相似
mov bx,1000H
mov ds,bx
mov [0],al

3.3 字的传送

8086CPU是16位结构,有16根数据线,所以可以一次传送16位数据,就是一个字,只要用mov指令给出16位的寄存器就可以直接进行16位数据的传送。比如
mov bx,1000H
mov ds,bx
mov ax,[0]
mov [0],cx
汇编前十三章汇总(复习用)
汇编前十三章汇总(复习用)
这里就可以说明小端方式的内存读取的起始地址的问题。

3.4 mov、add、sub指令

  1. MOV指令的几种形式
    mov 寄存器,数据 比如:mov ax,8
    mov 寄存器,寄存器 比如:mov ax,bx
    mov 寄存器,内存单元 比如:mov ax,[0]
    mov 内存单元,寄存器 比如:mov [0],ax
    mov 段寄存器,寄存器 比如:mov ds,ax
    mov 内存单元,立即数 比如:mov byte ptr DS:[0], 10
    最后一条要注意 给出的内存单元必须指定写入或读取的长度,如byte或word,必须给出段地址:[偏移地址]

  2. add指令
    add ax,8
    add ax,bx
    add ax,[0]
    add [0],ax
    add byte(word) ptr ds;[0],9
    但是注意的是不能 add 段寄存器,立即数或者寄存器

  3. sub指令
    和add指令一样,为减指令,用前面一个减去后面一个,结果存在前一个。

3.5 数据段

可以根据需要,将一组内存单元定义为一个段。我们可以将一组长度为N(N<= 64KB)、地址连续、起始地址为16的倍数的内存单元作为专门存储数据的内存单元,从而定义了一个数据段。
如123B0H ~ 123B9H这样的一段内存单元作为数据段,起始地址为123B0H,段地址为123BH,长度为10字节。

3.6 栈

规则:LIFO(Last In First Out,后进先出)

3.7 CPU提供的栈机制

8086CPU 提供入栈和出栈的指令,分别是:PUSH(入栈)和POP(出栈)。比如push ax,将ax的数据送入栈中,pop ax,将栈顶数据取出送入ax中。

现在有俩个问题:
第一:如果我们将10000H ~ 1000FH作为栈空间来使用,CPU如何知道这是栈空间?这个时候就要设置SS(栈段寄存器)的段地址,MOV ax,1000H MOV ss,ax
第二:如何知道栈顶的偏移地址,这个时候就要SP(堆栈指针寄存器)出场,设置SP,MOV sp,0010H。
再8086CPU中 push和pop操作也是符合小端方式存储和取出。
push ax的执行,由以下俩步完成。
(1)SP = SP - 2,SS:SP指向当前栈顶的单元,以当前栈顶前面的单元为新的栈顶;
(2)将ax中的内容送入SS:SP所指向的内存单元处,SS:SP此时指向新的栈顶。
如图汇编前十三章汇总(复习用)
pop ax的执行和push ax的执行正好相反。
(1)将SS:SP指向的内存单元的出书送入ax
(2)SP=SP+2,SS:SP指向当前栈顶下面的单元,以当前栈顶下面的单元为新的栈顶。
如图
汇编前十三章汇总(复习用)

3.8 栈顶超界问题

8086CPU不保证对栈的操作会不会出界,这个只能靠自己估算安排。一旦出界可能会修改栈外的内存单元的数据。

3.9 push、pop指令

push和pop指令的格式可以如下:
push 寄存器
pop 寄存器
push 段寄存器
pop 段寄存器
push 内存单元
pop 内存单元

第五章 [BX]和loop指令

1.[bx] 和内存单元的描述
[bx],就相当于[0],bx作为偏移地址

2.loop指令
这是一个循环指令,默认的计数器为cx,及cx表示循环的次数,在每一次循环的末尾cx-1,到cx为0退出循环。
如代码
mov cx, 3
mov bx,0
mov dx,0
s: mov al, ds:[bx]
mov ah,0
add dx,ax
inc bx
loop s

3.定义()
(ax)表示ax的内容,(20000H)表示20000H单元里面的内容。
((ds)*16+(bx)) 表示偏移地址为bx,段地址为ds的内存单元里面的内容。

4.约定符号idata表示常量

5.1 [BX]

用法就是BX作为偏移地址。
这里有一个指令
inc bx 表示bx自加一,比add bx,1要快不少

5.2 Loop指令

用cx寄存器来存放循环次数
格式为
标号:循环代码
loop 标号
如:
s:mov ax,1
loop s
CPU在执行loop时要进行俩步操作: (1) (cx) = (cx) - 1 (2) 判断cx的值,不为0则跳转值标号处执行程序。
不管cx的值,循环段代码至少执行1次。

5.5 [bx]和loop结合使用

相当于就是循环加可变的偏移值

5.6 段前缀

段前缀就是如同 ds:[bx] 里面的ds:
有 ds: cs: ss: es: 这些称为段前缀

5.7 一段安全的空间

一般来说在dos方式下,0:200 ~ 0:2ff ( 00200H ~ 002ffH ) 的256个字节空间是不会有程序使用的。
所以这一段空间是安全的。不过为了安全起见,进入DOS后可以Debug查看一下这一段空间是不是都为0.

所以以后向一个段中写入内容时,使用0:200 ~ 0:2ff 这段空间

第七章 更灵活的定位内存地址的方法

7.1 and 和 or 指令

(1)and 指令:逻辑与指令,按位与运算。
(2)or指令:逻辑或指令,按位或运算。

7.2 关于ASCII码

“a”的ASCII码为61H(0110 0001b),“A”的ASCII码为41H(0100 0001b)
大小写转化的时候,小写转为大写只要 -20H 或者 and(1101 1111b)就行。
相应的,大写转化为小写只要 +20H 或者 or (0010 0000b)就行。当然还可以是其他的答案,不影响转化就行。

7.5 [bx+idata]

含义是:偏移地址为 (bx) + idata
可以写成:
mov ax, [bx+idata]
mov ax, idata[bx]
mov ax, [bx].idata

7.6 用[bx+idata]的方式进行数组的处理

比如将datasg 中定义的第一个字符串转化为大写,第二个字符串转化为小写。
汇编前十三章汇总(复习用)
代码段:
汇编前十三章汇总(复习用)

7.7 SI和DI

si 和 di 是8086CPU 中和bx功能相近的寄存器,只是 si 和 di 不能分成两个 8 位寄存器来使用。

7.10 不同的寻址方式的灵活运用

(1)[idata] 用一个常量来表示地址,可以直接定位一个内存单元
(2)[bx],[si],[di] 用一个变量来表示内存地址,可以用于间接定位一个内存单元
(3)[bx+idata]
(4)[bx+si] si可以换成di
也可以写成:[bx][si]
(5)[bx+si+idata] si 可以换成 di

第八章 处理数据的俩个基本问题

这俩个认问题是:
(1)处理的数据在什么地方?
(2)要处理的数据有多长?

reg表示以恶搞寄存器,sreg表示一个段寄存器
reg的集合包括:ax、bx、cx、dx、ah、al、bh、bl、ch、cl、dh、dl、sp、bp、si、di;
sreg的集合包括:da、ss、cs、es。

8.1 bx、si、di和dp

汇编前十三章汇总(复习用)

8.4 寻址方式

汇编前十三章汇总(复习用)

8.5 指令要处理的数据有多长

8086 CPU 的指令,可以处理俩种尺寸的数据,byte 和 word,所以在机器指令中要指明指令进行的是字操作还是字节操作,
(1)通过指定寄存器名指明要处理的数据的尺寸。
如指定是 ax 还是 al 等

(2)在没有寄存器的名称存在的时候,用操作符 x prt 指明内存单元的长度, x 在汇编指令中可以是 word(字)或者 byte(字节)。
如:
mov word ptr ds:[0], 1
inc word ptr [bx]
mov byte ptr ds:[0], 1
inc byte ptr [bx]等

(3)其他方法
有些指令默认访问的是字单元还是字节单元,比如push 指令只进行字操作。

8.7 div 指令

div 是出发指令,使用div 做除法的时候要注意以下问题。
(1)除数:有8位和16位俩种,在一个reg或内存单元中
(2)被除数:默认放在AX 或 DX和AX中,如果除数为8位,被除数则为16位,默认放在AX中;如果除数位16位,被除数则位32位,存放在DX和AX中,DX存放高16位,AX存放低16位。
(3)结果,若除数为8为,则AL存放商,AH存放余数。若除数为16位,AX存放商,DX存放余数。

汇编前十三章汇总(复习用)

汇编前十三章汇总(复习用)

8.8 伪指令dd

db 和 dw 定义字节型数据和字型数据。dd是用来定义dword(double word,双字)型数据的,占俩个字。

dup

汇编前十三章汇总(复习用)

汇编——第九章转移指令的原理

** 可以修改IP,或者同时修改CS 和IP 的指令统称为转移指令。**概括来讲,转移指令就是可以控制CPU执行内存种某处代码的指令。

汇编前十三章汇总(复习用)

9.1 操作符 offset

汇编前十三章汇总(复习用)

9.2 jmp 指令

jmp为无条件转移指令,可以只修改IP也可以同时修改CS和IP。
jmp指令要给出两种信息:
(1)转移的目的地址
(2)转移的距离(段间转移、段内短转移、段内近转移)

9.3 依据位移进行转移的jmp指令

jmp short 标号(转移到标号处执行指令)
这种实现的时段内短转移,它对IP的修改范围为-128 ~ 127,也就是说它向前最多转移128个字节,向后转移最多127个字节。jmp指令中的“short”符号说明指令是短转移。jmp指令中的“标号”是代码段中的标号,指明了指令要转移的目的地,转移指令结束后,CS:IP应该指向标号处的指令。
汇编前十三章汇总(复习用)

9.6 转移地址在内存中的jmp指令

转移地址在内存中的jmp指令有两种格式。
(1)jmp word ptr 内存单元地址(段内转移)
功能:从内存单元地址处开始存放着一个字,是转移的目的偏移地址。
(2)jmp dword ptr 内存单元地址(段间转移)
功能:从内存单元地址处开始存放着两个字,高地址处的字是转移的目的段地址,低地址处是目标的偏移地址。
(CS)=(内存单元地址+2)
(IP)=(内存单元地址)

9.7 jcxz指令

jcxz指令是一个有条件转移指令所有的条件住哪一指令都是短转移。 IP的修改范围都为:-128 ~ 127。
指令格式:jcxz 标号(如果(CX) = 0,转移到标号处执行。)
其功能的解释相当于:if((CX) == 0) jmp short 标号。

9.8 loop 指令

loop 指令为循环指令,所有的循环指令都是短转移。IP修改的范围为:-128 ~ 127.
指令格式:loop 标号((CX) = (CX) - 1, 如果(CX) != 0,转移到标号处执行。)

9.9 根据唯一进行转移的意义

汇编前十三章汇总(复习用)

第十章 CALL和RET指令

call 和 ret 指令都是转移指令, 他们都修改IP, 或者同时修改CS 和 IP。 它们经常被共同用来实现子程序的设计。

10.1 ret 和 retf

ret指令用栈中的数据,修改IP的内容,从而实现近转移;
retf指令用栈中的数据,修改CS和IP的内容,从而实现远转移;

CPU执行ret指令时,进行下面俩步操作:
(1)(IP) = ((ss)*16 +(sp));
(2)(sp) = (sp) + 2

CPU执行retf指令时,进行下面四个操作:
(1)(IP)=((ss)*16 + (sp));
(2)(sp)= (sp) + 2;
(3)(CS)= ((ss) *16 + (sp));
(4)(sp) = (sp) + 2;

ret 相当于 pop IP;
retf 相当于 pop IP , pop CS;

所以使用 retf 的时候, 先压入CS在压入IP。

10.2 call 指令

CPU执行call 指令的时候,进行俩步操作:
(1)将当前的IP或者CS和IP压入栈中;
(2)转移;

10.3 依据位移进行转移的call 指令

call 标号(将当前的IP压入栈后,转移到标号处执行指令)
CPU执行此种格式的call指令时,进行如下操作:
(1)(sp) = (sp) - 2;
(2)((ss) *16 + (sp)) = (IP);
(3)(IP) = (IP) + 16位位移。
16位位移=标号处地址-call指令后的第一个字节的地址;
16为位移的范围为-32768 ~ 32767;
call 标号 相当于 push IP ;jmp near ptr 标号

10.4 转移的目的地址在指令中的call指令

“call far ptr 标号” 实现的是段间转移。
汇编前十三章汇总(复习用)

10.5 转移地址在寄存器中的call指令

汇编前十三章汇总(复习用)

10.6 转移地址在内存中的call指令

转移地址在内存中的call指令由俩种格式。
(1)call word ptr 内存单元地址
相当于 push IP; jmp word ptr 内存单元地址
(2)call dword ptr 内存地址单元
相当于 push CS; push IP; jmp dword ptr 内存单元地址

10.7 call 和 ret 的配合使用

汇编前十三章汇总(复习用)
汇编前十三章汇总(复习用)

10.8 mul 指令

(1)两个相乘的数,要么都是8位,要么都是16位。如果是8位一个默认放在AL中,另一个放在8位reg或者内存单元中;如果是16位,一个默认在AX中,另外一个放在16位reg或者内存单元中。
(2)结果:如果是8位乘法,结果默认放在AX中,如果是16位乘法,结果高位默认放在DX中,低位在AX中。
汇编前十三章汇总(复习用)

10.9 模块化程序方法

使用call 和 ret 设计子程序可以实现模块化程序设计

10.10 参数和结果传递问题

汇编前十三章汇总(复习用)

10.11 批量数据的传递

如果数据有很多个,单纯的寄存器个数满足不了需求,**这个时候会可以将批量数据存在内存中,然后将他们所在的内存空间的首地址放在寄存器中,传递给需要的子程序。对于具有批量数据的返回结果,也可以使用同样的方法。
比如下面例子:
汇编前十三章汇总(复习用)

10.12 寄存器冲突的问题

设计一个子程序,将data段中的字符串全部转化为大写。
下面代码是错误的,错误分析在代码后面说明
汇编前十三章汇总(复习用)
汇编前十三章汇总(复习用)
这里很容易发现子程序修改了cx和si的值,出现错误。
这个时候可以使用堆栈来存CX和si的值。
汇编前十三章汇总(复习用)

第十一章 标志寄存器

标志寄存器具有以下三个作用:
(1)用来存储相关指令的某些执行结果;
(2)用来为CPU执行相关指令提供行为依据;
(3)用来控制CPU的相关工作方式。
汇编前十三章汇总(复习用)

11.1 ZF标志

flag的第6位是ZF,零标志位。他记录相关的指令执行后,其结果是否为0。如果为0那么ZF=1;反之ZF=0;

注意:在8086CPU指令集中,有的指令的执行是影响标志寄存器的,比如,add、sub、mul、div、inc、or、and等,它们大都是运算指令(进行逻辑或算术运算);有的指令的执行对标志寄存器没有影响,比如,mov、push、pop等,它们大都是传送指令。

11.2 PF标志

flag的第2位是PF,奇偶标志位。它相关指令记录执行后,其结果的所有bit位中1的个数是否为偶数。如果1为偶数,pf=1,如果为奇数,那么pf=0.

11.3 SF标志

flag的第7位是SF,符号标志位。它记录相关指令执行后,其结果是否为负。如果结果为负,sf=1;如果非负,sf=0。

在计算机中通常使用补码来表示有符号数据。计算机中的一个数据可看称是是有符号数,也可以看成是无符号数。比如:
00000001B可以看成无符号数1,或者有符号数+1;
10000001B可以看成无符号数129,或者有符号数-127.
汇编前十三章汇总(复习用)

11.4 CF标志

flag的第0为是CF,进位标志位。一般情况下,在进行无符号数运算的时候,它记录了运算结果的最高有效位向更高位的进位值,或者从更高位的借位值。
汇编前十三章汇总(复习用)

11.5 OF标志

flag的第11位是OF,溢出标志位。一般情况下,OF记录了有符号数运算的结果是否发生了溢出。如果发生溢出,OF=1;如果没有,OF=0。

11.6 adc指令

adc是带进位加法指令,它利用CF位上记录的进位值。

指令格式:adc 操作对象1, 操作对象2
功能:操作对象1 = 操作对象1 + 操作对象2 + CF。

adc和add的配合就可以对更大的数据进行加法运算。

11.7 sbb指令

sbb是带借位减法指令,它利用了CF位上记录的借位值。

指令格式:sbb操作对象1,操作对象2
功能:操作对象1 = 操作对象1 - 操作对象2 - CF。

sbb和sub的配合就可以对更大的数据进行减法运算。

11.8 cmp指令

cmp是比较指令,cmp的功能相当于减法指令,只是不保存结果。cmp指令执行后,将对标志寄存器产生影响。其他相关指令通过识别这些被影响的标志寄存器位来得知比较的结果。

cmp通常和条件转移指令相配合。

11.9 检测比较结果的条件转移指令

“转移”指的是它能够修改IP,而“条件”指的是它可以根据某种条件。决定是否修改IP。
比如jcxz就是一个条件转移指令,它可以检测cx中的数值,如果(cx)=0,就修改IP,否则什么也不做,所有的条件转移指令的转移位移都是[-128,127]。

cmp通常和条件转移指令相配合,cmp可以同时进行俩种比较,也就是无符号数比较和有符号数比较。所以更具cmp指令的比较结果进行转移指令也分为两种,即根据无符号数的比较结果进行转移的条件转移指令(它们检测zf和cf)和根据有符号数的比较结果进行转移的条件转移指令(它们检验sf、pf和zf的值)。

汇编前十三章汇总(复习用)

11.10 DF标志和串传送指令

flag的第10位是DF,方向标志位。在串处理指令中,控制每次操作后si、di的递减。
df=0 每次操作后si、di递增;
df=1 每次操作后si、di递减。

对于串传送指令。
格式:movsb
功能:执行movsb指令相当于进行以下几个操作。
(1)((es) *16 + (di)) = ((ds) *16 + (si))
(2)如果df=0 则, (si)=(si)+ 1;(di)=(di)+ 1;
. 如果df=0 则, (si)=(si)- 1;(di)=(di)- 1;
movsb是将ds:si指向的内存单元中的字节送入es:di中,然后更具标志寄存器df位的值,将si和di递增或递减。

对于传送字的串传送指令如下。
格式:movsw
功能:将ds:si指向的内存字单元中的字送入es:di中,然后根据标志寄存器df位的值,将si和di递增2或递减2。

一般来说movsb和movsw都和rep配合使用,格式如下。
rep movsb 或 rep movsw
相当于:
s:movsb
loop s
rep的作用就是根据cx的值,重复执行后面的串传送指令。

设置df的指令。
在8086CPU中,有两条指令对df位进行设置。
cld指令:将标志寄存器的df位置设置为0;
std指令:将标志寄存器的df位置设置为1。

两个例子
汇编前十三章汇总(复习用)

汇编前十三章汇总(复习用)

11.11 pushf和popf

pushf的功能是将标志寄存器的值压栈,而popf是从栈中弹出数据,送入标志寄存器中。
pushf和popf,为直接访问标志寄存器提供了一种方法。

11.12 标志寄存器在Debug中的表示

汇编前十三章汇总(复习用)

第十二章 内中断

12.1 内中断的产生

CPU内部有下面的情况发生的时候,将产生生相应的终端信息。
(1)除法错误,比如,执行div指令产生的除法溢出;
(2)单步执行;
(3)执行into指令;
(4)执行int指令。
在8086 CPU中,上述4种中断信息的来源,简称中断源,在8086CPU 中的中断类型码如下。
分别为(1)0(2)1(3)4(4)n,int 指令的格式为int n,指令中的n为字节型立即数,是提供给CPU的中断类型码。这个n最大为255。

12.2 中断处理程序

CPU在收到中断信息后,就要转去执行中断信息的处理程序,需要找到相应的CS和IP,而中断类型码可以在中断向量表中找到一个地址,这个地址存储了相应的CS和IP。

12.3 中断向量表

汇编前十三章汇总(复习用)
汇编前十三章汇总(复习用)

12.4 中断过程

汇编前十三章汇总(复习用)
汇编前十三章汇总(复习用)
汇编前十三章汇总(复习用)

12.5 中断处理程序和iret指令

汇编前十三章汇总(复习用)

12.6 除法错误中断的处理

除法中断是0号中断。对于下面程序,1000h除以1得到1000h,可知是8位除法,商1000h存放在al中,发生溢出,产生0号中断。
汇编前十三章汇总(复习用)

12.7 编程处理0号中断

我们现在考虑一下改变0号中断吃力程序的功能,功能是在屏幕中间显示“overflow!”,然后返回操作系统。
汇编前十三章汇总(复习用)
汇编前十三章汇总(复习用)
汇编前十三章汇总(复习用)
汇编前十三章汇总(复习用)

12.8 安装

可以使用movsb指令,将do0的代码送入0:200处。程序如下
汇编前十三章汇总(复习用)
汇编前十三章汇总(复习用)

12.9 do0

首先我们看下面的程序,这个程序是不对的
汇编前十三章汇总(复习用)
汇编前十三章汇总(复习用)
汇编前十三章汇总(复习用)
汇编前十三章汇总(复习用)
最后的就是设置中断向量了。

12.10 设置中断向量

汇编前十三章汇总(复习用)

12.11 单步中断

汇编前十三章汇总(复习用)
汇编前十三章汇总(复习用)

12.12 响应中断的特殊情况

汇编前十三章汇总(复习用)
汇编前十三章汇总(复习用)

3# 第十三章 int指令

13.1 int指令

int 指令的格式为:int n,n为中断类型码,它的功能是引发中断过程。
CPU执行int n指令,相当于引发一个n号中断过程,过程如下:
(1)取中断类型码n;
(2)标志寄存器入栈,IF = 0, TF = 0;
(3)CS、IP入栈;
(4)(IP) = (n *4),(CS) = (n *4+2);

13.2 编写供应用程序调用的中断例程

汇编前十三章汇总(复习用)
汇编前十三章汇总(复习用)
汇编前十三章汇总(复习用)
汇编前十三章汇总(复习用)
汇编前十三章汇总(复习用)
汇编前十三章汇总(复习用)

13.3 对int、iret和栈的深入理解

汇编前十三章汇总(复习用)
汇编前十三章汇总(复习用)

13.4 BIOS和DOS所提供的中断例程

汇编前十三章汇总(复习用)

13.5 BIOS和DOS中断例程的安装过程

汇编前十三章汇总(复习用)
汇编前十三章汇总(复习用)

13.6 BIOS中断例程应用

汇编前十三章汇总(复习用)
汇编前十三章汇总(复习用)
汇编前十三章汇总(复习用)
汇编前十三章汇总(复习用)

13.7 DOS中断例程应用

汇编前十三章汇总(复习用)
汇编前十三章汇总(复习用)
汇编前十三章汇总(复习用)

  1. BP寄存器
    它的确是一个寄存器,名字叫基址指针,是16位,它的用途有点特殊,是和堆栈指针copySP联合使用的,作为SP校准使用的,只百有在寻找堆栈里的数据和使用个别的寻址方式时候才能用到。
    比如说,堆栈中压入了很多数据或者地址度,你肯定想通过SP来访问这些数据或者地址,但SP是要指向栈顶的,是不能随便乱改的,这时候你就需要使用BP,把SP的值传递给BP,通过BP来寻找堆栈里数据或者地址。
    ————————————————
    版权声明:本文为****博主「放过@」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.****.net/wxy2635618879/article/details/105512391