汇编语言基础

汇编语言(8086)

一、寄存器

  1. 寄存器:CPU中可以储存数据的器件,一个CPU中可以有多个寄存器

  2. AX,BX,CX,DX为通用寄存器

  3. 名称不分大小写

  4. 存储的数据是从后向前的(小端)

  5. 对低位进行计算产生溢出得到的结果也不会转移到高位中去

  6. 一个16位寄存器可以分为两个八位的寄存器进行使用AX分为AH与AL

  7. 段寄存器:CS,DS,SS,ES CPU要访问内存时由他们进行内存单元段地址的提供

  8. CS与IP是最关键的寄存器,他们指示了CPU当前要读取指令的地址

    pc工作过程:根据地址到内存单元中读取指令,放入缓冲器,IP进行加上读取指令的长度,从而指向下一条指令

    在CPU加电启动或复位后(即CPU刚开始工作时)CS和IP被设为CS=FFFFH,IP=0000H会从这里读取指令进行执行,为开机后的第一条指令

  9. 不支持直接将数据直接放入段寄存器中,需借助通用寄存器

  10. 可以将段寄存器中的值传入到寄存器中

二、存储器

  1. CPU是计算机的核心部件,控制整个计算机的运作并进行运算,想让一个CPU进行互作,必须向他提供指令和数据

  2. 一个储存器有128个存储单元也就是128Byte

  3. 指令和数据在存储器中存放,也就是平时说的内存。磁盘不同于内存,磁盘上的数据或程序如果不读到内存中,就无法被CPU执行

  4. CPU要进行数据的读写,必须和外部器件(标准的说法是芯片)进行三类信息的交互:

    ·储存单元的地址(地址信息)

    ·器件的选择,读或写的命令(控制信息)

    ·读或写的数据(数据信息)

  5. 储存器芯片

    BIOS基本输入输出系统,是由主板和各类接口卡(显卡、网卡等)厂商提供的软件系统,可以通过他利用该硬件设备进行最基本的输入输出。在主板和某些接口卡上插有存储相应的BIOS的ROM

  6. RAM(主存储器)0000

    ROM(装有系统BIOS)

    RAM(主存储器)内存条,扩展卡槽

    RAM(显存)ROM(装有显卡BIOS) 显卡,扩展卡槽 9FFFF A0000

    ROM(装有网卡BIOS) 网卡,扩展卡槽 BFFFF C0000

    都与CPU的总线相连

  7. 随机存储器(RAM)

    用于存放CPU使用的绝大部分程序和数据主要由装在主板上的和插在扩展卡槽上的,可读可写,关机后内容丢失。

  8. 接口卡上的RAM

    某些接口卡需要大批量输入,输出数据进行暂时储存,上面就装有RAM。最典型的是显卡上的,称为显存。显示卡随时将显存中的数据向显示器上输出。将内容写入显存就会出现在显示器上。

  9. 只读存储器(ROM)

    储存着BIOS,BIOS是由主板和各类接口卡厂商提供的软件系统。关机后内容不丢失。

  10. 存储单元的地址用两个元素进行描述,段地址与偏移地址

    表示2000:1F60

  11. 将数据从寄存器送入内存单元

    mov bx,1000H

    mov ds,bx

    mov [0],cx

    mov ax,[0]

    字在内存中储存时,要用两个地址连续的内存单元来进行存放,低位放在低的地址单元中,高位放高位

    用mov访问内存单元时可以直接给出偏移地址,段地址默认在DS寄存器中[偏移地址]

三、数据总线

  1. 和计算机的位数相关
  2. 总线的宽度决定与其他器件进行数据传送时一次传送数据的量
  3. 8根数据总线可以一次传送一个字节

四、地址总线

  1. 一根导线可以传送的稳定状态只有两种,高电平或低电平。用二进制表示就是0或1
  2. 一个CPU具有N根地址总线,就可以说地址总线的宽度为N,这样CPU最多可以寻找2的N次方个内存单元

五、控制总线

  1. 读写的命令是由几根控制总线共同发出的

    其中有一条名为信号读信号输出控制线负责由CPU向外传出读写信号,CPU向该控制线上输出低电表示要读取数据

    有一条名为写信号的输出控制线则负责由CPU向外传送写信号

  2. 总线的宽度决定对其他控件的控制能力

六、CPU

  1. 由运算器(信息处理)、控制器、寄存器(信息储存 )等器件组成,器件之间依靠总线相连(内部总线)

  2. 外部总线实现CPU和主板的其他器件的联系

  3. 一个CPU芯片都有许多的管脚,管脚与总线相连,可以说管脚引出总线。

  4. 16位表示

    计算器一次最多可以处理16位的数据,也就是一个字

    寄存器的最大宽度为16位

    寄存器与运算器之间的通路是十六位的

  5. 给出物理地址的方法

    其他部件将段地址和偏移地址传递给地址加法器(16位)地址加法器进行处理后输出物理地址(20位)输入输出的控制电路通过地址总线(20位)找到内存中的数据

  6. 地址加法器的工作原理

    相关部件提供段地址和偏移地址,将段地址✖16加上偏移地址得到物理地址,最后进行输出

  7. 每一台PC中都有一个主板,主板上有核心器件和一些主要器件通过总线相连接。包括CPU,存储器,外围芯片组,扩展插槽

七、jmp

  1. jmp ax类似于(mov IP,ax)

    jmp bx

    用寄存器中的值修改IP

  2. 后加地址直接改变地址

  3. 需要转移的目的地址与转移的距离(段间转移,段内短转移,段内近转移)

  4. jmp short s

    add ax,1

    s:inc ax

    对应的机器码为EB03,意味着CPU并不知道转移的目的地址

    cs Ip指向EB03,读取指令进入指令缓冲器,IP=(IP)+所读取指令的长度,然后指向紧接着的下一条指令,执行缓冲器中的指令,然后指向跳转的地方

    转移的为偏移地址

  5. jmp near ptr (IP)=(IP)+16位位移 16位位移=标号处的地址—jmp指令后第一个字节的地址 范围为-32768~32767

  6. jmp far ptr 标号(远转移)包含了目的地址的段地址与偏移地址

  7. jmp word ptr 内存单元地址,从内存单元地址处放着一个字,是转移目的的偏移地址,mov ax,0123H mov ds:[0],ax jmp word ptr ds:[0]

    最后IP为0123H

  8. jmp dword ptr 内存单元地址,高处地址为转移的目的段地址,低地址为转移的目的的偏移地址,mov ax,0123H mov ds:[0],ax mov word ptr ds:[2],0 jmp dword ptr ds:[0]

    执行后(cs)=0,(IP)=0123H

八、DEBUG

  1. R指令查看和改变CPU寄存器的内容
  2. D命令查看内存中的内容 1000:0 9查看这个地址前九个内容
  3. E指令改写内存中的内容 后接地址进行修改,修改后用空格到下一个,或者直接用空格到下一个,还可以直接写入字符串
  4. U命令将内存中的指令翻译成汇编指令
  5. T命令执行一条机器指令
  6. A命令以汇编指令的格式在内存中写入一条机器指令

九、栈

  1. 一种具有特殊访问方式的存储空间,最后入栈最先出去
  2. 入栈将一个新的元素放到栈顶push SP先减2后放入
  3. 出栈从栈顶取出一个元素pop 先取出后SP减2
  4. lsst in first out
  5. 是以字为单位进行的
  6. SS寄存器为栈顶的段寄存器
  7. SP存放栈顶的偏移地址,空栈的时候指向栈顶的下一位单元
  8. SS:SP指向栈顶第一个元素
  9. 将10000H-1FFFFH这段空间当成栈时SP=0
  10. 栈顶的变化范围是0-FFFFH
  11. 如果栈空的时候SP=0一直将栈压满,如果再次进行压栈,栈顶将环绕覆盖原来栈中的内容
  12. 在进行出栈的时候已经出来的不再栈内了但是仍然存在这时在对栈进行写入就会替代原来的内容

十、段

  1. 可以将一段内存定义为一个段,用一个段地址指示段,用偏移地址来访问段内的单元,可以用作数据段,代码段,栈段,分别与相应的寄存器进行链接

  2. 在源程序中date数据段,code代码段,stack栈段

  3. mov ax,stack

    mov ss,ax

    mov sp,16

    设置ss指向stack设置ss:sp指向stack:16,CPU执行这些指令后,将把stack段当作栈空间来使用

  4. 程序获取空间的方法有两种,一是在加载程序的时候为程序分配,再就是程序执行的过程中进行申请

  5. 在代码段中用dw可以定义所需要用到的数据,通过cs:[bx]进行引用

  6. 段名相当于一个标号,代表了段地址可以将他与段寄存器相连来达到对定义段地址的引用,且要借助于通用寄存器

十一、编写汇编源程序

  1. 文本编辑器(记事本,Nodepad++,UltraEdit)

  2. 伪指令:没有对应机器码的指令,最终不被CPU执行 ,由编译器执行。 除了start后面的是汇编指令其他的都是伪指令。符号计算机也不执行,也是由编译器进行执行。

  3. 伪指令是由编译器来执行的指令,编译器根据伪指令来进行相关的编译工作

  4. segment和ends是成对使用的伪指令,汇编程序必须要有的,功能为定义一个段,分别为段的开始与结束。一个段必须有一个名称来标识,段名+segment

  5. 代表了一个地址,最终被编译连接程序处理为一个段地址

  6. 一个有意义的汇编程序至少有一个段,来存放代码

  7. assume意为假设,假设某一段寄存器与程序中的某一个段相关联。

  8. 程序的返回mov ax,4c00H int 21H实现程序返回

  9. 在DOS中,可执行文件中的程序P1若要运行,必须有一个正在运行的程序P2将P1c从可执行文件中加载入内存,将CPU的控制权交给他才可以执行,完成之后再将控制权交还

  10. 在DOS中直接执行1.exe时,是正在运行的command将程序加载入内存,并设置CPU的CS:IP指向程序的第一条指令

    在用Debug进行跟踪的时候command首先加载Debug然后再由Debug对程序进行加载

    返回也是先返回到Debug再到command

    要使用p命令来执行int 21

    使用Q,命令退出Debug

  11. 汇编程序从写出到执行的过程:1.asm编程,编译1.obj,连接1.exe,加载(command),内存中的程序,运行(CPU)

  12. exe文件的加载过程:找到一段起始地址偏移地址为0的容量足够的空间内存区,在这段内存区的前256个字节中创建一个称为程序的前缀(PSP)的数据区,DOS要利用PSP来和被加载的程序进行通信,在后面将程序装入起始地址为原来的段地址+10H:0000H。二者的物理地址连续但分为两个不同的段,将该内存区的地址存入DS中,初始化其他相关寄存器后将CS:IP指向程序的入口

  13. 描述性符号()

    (ax)=0010H来表示ax中的值

    2000:1000处的内容为0010H可表示为(21000H)=0010H

    对于mov ax,[2]可表示(ax)=((ds)*16+2)

  14. 在汇编源程序中,数据不能以字母开头,所以在大于9FFFH的前面加0

  15. 在汇编源程序中[0]不会被看作偏移地址中的值而是直接被当作0来处理

    可以将0先给予bx然后再对[bx]操作可以达到想要的效果

    或者ds:[0]段前缀加偏移地址

  16. 一段安全的空间,CPU一般不会使用0:200-0:2FF的256空间

  17. end的作用:除了通知编译器程序结束之外,还可以告诉编译器程序的入口在哪里,后接的start一开始出现的地方就是程序开始的地方,被转化为一个入口地址

  18. assume cs:code,ds:date,ss:stack //将他们关联起来

    date segment

    dw 0123H,0456H

    date ends// 定义数据

    stack segment

    dw 0,0,0,0,0

    stack ends //定义一段栈空间

    code segment

    start:

    mov ax,stack

    mov ss,ax

    mov sp,16 //初始化栈段

    mov ax,date

    mov ds,ax//初始化数据段

    其他代码

    mov ax,4c00h

    int 21h//退出

  19. 在debug中mov [0]可以实现对偏移地址为0的数据进行操作,但是在源程序中这种写法是不被认可的,会将他当作数值0进行操作

  20. 源程序中可以用[bx]或段寄存器(段前缀):[idata]

十二、Loop指令

  1. CPU执行时进行两步操作(cx)=(cx)-1 判断cx中的值,不为0则转至标号处执行程序 cx中存放循环的次数
  2. 标号后面为执行的内容,执行Loop就跳转到标号的位置进行循环
  3. 在进行字节向字传送数值时可以将字的高位设为0低位与字节数据进行值的传递
  4. 在进行调试的时候遇到loop指令的时候使用p来进行执行,就会自动重复命令得到最后的结果
  5. 可以使用g加上偏移地址直接进行跳转

十三、and与or指令

  1. and相当于&&有0则0
  2. or相当于||有1则1

十四、以字符形式给出的数据

  1. 可以在数据段中进行db 'unIX'相当于db 75H 6EH 49H 58H

  2. 大小写进行转换,由于大小写字母的ASCII相差32,将他的第六位二进制数置为0或1,用and置零,用or置1

    mov bx,0

    mov al,[bx]

    and al,11011111

十五、利用[bx+idate]的方式进行数组的处理

  1. 数据的偏移地址为bx与idate(常数)的和

  2. 可以用来同时对两个不同的字符串采取相同的操作

  3. si与di是与bx用法类似的寄存器,可以满足对多个数据处理时对bx的反复赋值,但不能分成两个八位的寄存器来使用

  4. C语言对字符串的定位方式:a[i],b[i]

    汇编语言的定位方式:0[bx],5[bx]可以看出ab代表的是字符串的首地址

  5. [bx+si+idate]

    两个变量一个常量,二维数组

  6. 在进行双重循环的时候由于内外都改变cx的值会造成错乱,在第一层循环外对cx进行赋值操作,在第一次循环开始时将cx的值储存起来,再设置内层循环的次数,在第二层循环结束的时候再将储存起来的cx值进行恢复

  7. 如果需要保存的值一些通用的寄存器不够用达不到需要的时候就可以将这些值储存在内存单元中

  8. 但是一般来说进行数据的暂存的时候都会使用栈

十六、数据处理的两个基本问题

  1. 处理的数据在什么地方,要处理的数据有多长

  2. 用reg来表示一个寄存器:ax,bx,cx,dx,ah,al,bh,bl,ch,cl,dh,dl,sp,bp,si,di

  3. 用sreg来表示段寄存器:ds,ss,cs,es

  4. 只有bx,bp,si,di可以用[ ]进行寻址

  5. 在[ ]中bx,di,si,bp可以单个出现也可以有四种组合,bx或bp分别与si或di

  6. 机器处理的数据在什么地方:一般来说在CPU的内部,内存,端口

  7. 而处理大致可以分为三类:读取,写入,运算

  8. mov bx,[0]内存

    mov bx,axCPU的内部,ax寄存器

    mov bx,1CPU的内部,指令缓冲器

  9. 数据位置的表达

    对于直接包含在计算机指令中的数据,称为立即数 mov ax,1

    处理的数据在寄存器中

    段地址和偏移地址 段地址是默认的

  10. 指令要读取的数据有多长,可以通过寄存器的位数来知道,对于没有寄存器的还可以直接用X ptr来进行指明,X可以是word或byte,对于栈内的默认为两个字节

  11. 一般可以用[bx+idata+si]的方式来访问结构体中的数据,也可以用类似C语言的写法,[bx].idata[si],bx定位整个结构体,idata定位结构体中的某个数据项,si来定位每个元素

  12. div指令

    除法指令,除数有8位和16位两种,在一个reg或内存单元中

    被除数默认放在ax或dx中,如果除数为八位则被除数为16位,如果除数为16位则被除数为32位,在ax,dx中存放dx放高16位,ax放低16位

    除数为8位则在al中储存得到的商,ah储存余数

    除数为16位则在ax中储存得到的商,在dx中储存得到的余数

    将超过65535的二进制数转换为十六进制的数据,再进行高低位的赋值操作

  13. 伪指令dd,用来定义双字节数据的

    在定义一个双字节的数据作为被除数的时候可以mov ax,ds:[0] mov dx,ds[2]进行赋值的操作

  14. dup操作符用来进行数据的重复,一般与db,dw,dd来进行配合使用,db 3 dup (0)定义了三个字节值都为0

    db 3 dup (0,1,2)相当于定义了9个字节

十七、转移指令原理

  1. 可以修改ip(段内转移)或同时对cs,ip进行修改的指令(段间转移)统称为转移指令

  2. 段内转移又分为短转移和近转移,范围分别为-128-127,-32768~32767

  3. 转移又分为无条件转移jmp,条件转移指令,循环指令loop,过程,中断

  4. 操作符offset由编译器处理的符号,取得标号的偏移地址

    start:mov ax,offset start相当于mov ax,0

    s:mov ax,offset s相当于mov ax,3

  5. jcxz有条件的转移指令,都为短转移,对应的机器码中包含转移的位移,jcxz 标号,如果(cx)=0则进行跳转,不为0就什么也不做

  6. dec为自递减指令

十八、CALL和RET指令

  1. 他们都是转移指令,修改IP,或者同时修改CS,IP
  2. ret指令用栈中的数据,修改IP的内容,实现近转移 相当于pop IP
  3. retf指令用栈中的数据,修改CS与IP的内容从而实现远转移 相当于pop IP pop cs
  4. call指令,将当前的IP或CS和IP压入栈中,转移
  5. call 标号(将当前的IP压入栈中转移到标号进行操作)jmp near ptr 标号
  6. call far ptr 标号实现的是段间转移,push CS push IP jmp far ptr 标号
  7. call的用法与jmp十分的类似,只是将当前的地址内容压入栈

十九、mul指令

  1. 两个相乘的数:要么都是8位的,要么都是16位的
  2. 8位:al中和8位寄存器或字节内存单元中,结果默认放在ax中
  3. 16位:ax中和16位寄存器或内存字单元中,高位默认在dx中存放,低位在ax中存放
  4. mul reg、mul 内存单元、mul byte ptr ds:[0]
  5. 在循环内使用为了防止cx寄存器引起冲突发生错误,可以将cx的值在子程序的开始进行入栈保存,结束后再进行恢复

二十、标志寄存器

  1. 标志寄存器有十六位,其中储存的信息通常被称为程序状态字(PSW)

  2. 标志寄存器(flag)是按位起作用的,他的每一位都有专门的含义,记录特定的信息(1,3,5,12,13,14,15)没有使用

  3. ZF标志,第六位,零标志位,他记录相关指令执行后,结果为0,ZF=1,结果不为0,ZF=0

  4. PF标志,第二位,奇偶标志位,他记录指令执行后,结果的所有二进制位中1的个数如果有奇数个则PF=0,如果有偶数个则PF=1

  5. SF标签,第七位,符号标志位,执行后结果为负数,SF=1,结果为正,SF=0

  6. 如果将数据当作无符号数来进行运算,SF的值就没有意义

  7. CF标志,第零位,,进位标志位,一般情况下,在进行无符号的运算的时候,他记录了运算结果的最高有效位向更高位的进位值

  8. OF OV NV 值为1,0

    SF NG PL

    ZF ZR NZ

    PF PE PO

    CF CY NC

    DF DN UP

  9. OF标志,十一位,对于有符号的溢出,有为1,无为0

  10. DF标志,第十位,方向标志位。在串处理指令中,控制每次操作后si,di的增减,df=0每次操作后使他们递增,df=1每次操作后使他们递减

二十一、adc指令

  1. adc 操作对象1,操作对象2
  2. 操作对象1=操作对象1+操作对象2+CF
  3. 可以用作高位的运算

二十二、sbb指令

  1. 带位减法指令,利用CF上的借位值
  2. sbb操作对象1,操作对象2
  3. 操作对象1=操作对象1-操作对象2-CF

二十三、cmp指令

  1. cmp ax,ax 仅进行ax-ax的运算但是结果并不保存在ax中,只是利用计算对标志寄存器进行设置

  2. cmp ax,bx

    = ZF=1

    != ZF=0

    < CF=1

    大于 CF=0,ZF=0

    SF=1不能说明两个数的大小,可能是正数减去负数引起溢出得到负数,要看OF有没有溢出,如果溢出那么得到的符号与真实的结果是相反的

二十四、检测比较结果的条件转移指令

  1. 转移指的是可以修改IP的值,条件指的是判断是否对值进行修改,像jcxz

  2. 大多数是根据标志位的值来进行判断,通常与cmp进行配合使用

  3. je 等于则转移 zf=1(检测)

    jne 不等于则转移 zf=0

    jb 低于则转移 cf=1

    jnb 不低于则转移 cf=0

    ja 高于则转移 cf=0且zf=0

    jna 不高于则转移 cf=1或zf=1

二十五、串传送指令

  1. movsb作用将ds:si指向内存单元中的字节送入es:di中,然后根据df中的值对si,di进行操作

  2. df为第十位,使用cld指令:将标志寄存器的df设为0,std指令:将标志寄存器的df位设为1。

  3. movsw进行字的传送,然后对si,di进行加2或减2的处理

  4. df=0的时候进行递增操作,1的时候进行递减操作

  5. movsb和movsw都是串传送操作的一个步骤,一般与rep进行配合使用,rep movsb相当于:s:movsb loop s。rep的作用是根据cx的值,重复执行后面的串传送指令。每次可以自动指向下一个单元所以可以对cx个字符的传送

  6. 将data:0处的16个字符传送到data:0010

    mov ax,data

    mov ds,ax

    mov si,0

    mov es,ax

    mov di,16

    mov cx,16

    cld

    rep movsb

二十六、pushf和popf

  1. pushf:将标志寄存器的值压入栈
  2. popf:从栈中弹出数据,送入标志寄存器中
  3. pushf,popf为直接访问标志寄存器提供了一种方法

二十七、内中断

  1. 任何一个通用的CPU都具备一种能力,可以在执行完当前正在执行的指令之后,检测到从CPU外部发送过来的或内部产生的一种特殊信息,并且可以立即对接收到的信息进行处理,这种信息可以称之为中断信息。
  2. 中断是CPU内部处理外部突发事件的一个重要技术,使在运行中对外部事件发出的中断请求及时的进行处理,处理完成之后立即返回断点,继续进行原来的工作
  3. 引起中断的原因或发出中断请求的来源叫做中断源。根据中断源的不同可以将中断分为硬件中断和软件中断两大类,硬件中断又可以分为内部中断和外部中断两大类
  4. 外部中断一般是由计算机外设发出的中断请求,如:键盘中断、打印机中断、定时器中断。外部中断是可以屏蔽的中断,利用中断控制器可以屏蔽这些外部设备的中断请求
  5. 内部中断是指因硬件出错(如断电,奇偶校验出错等)或运算出错(除数为0,运算溢出,单步中断等)所引起的中断。内部中断是不可屏蔽的中断
  6. 软件中断其实并不是真正的中断,他们只是可被调用执行的一般程序以及DOS的系统功能调用(INT 21H)
  7. CPU为了能处理并发的中断请求,规定了终端的优先权,中断优先权由高到低的顺序是:除法错、溢出中断、软件中断,不可屏蔽中断,可屏蔽中断,单步中断。
  8. 内中断的产生,当CPU里面有以下情况发生的时候将产生相应的中断信息,除法错误,单步执行,执行into指令,执行int指令
  9. CPU首先要知道,接收到的中断信息的来源,所以中断信息必须包含识别来源的编码,8086称为中断类型编码,他是一个字节型的数据,可以表示256种中断信息的来源。中断信息的来源,简称为中断源,上面的四种分别用0,1,4和int n进行表示
  10. 用来处理中断的程序称为中断处理程序,一般来说要对不同的中断信息编写不同的程序

二十八、中断向量表

  1. 设计者必须在中断信息中判断处理程序的入口,然后在中断信息和处理程序的入口地址之间建立某种联系,中断类型码的作用就是用来定位中断处理程序,但要定位处理程序,需要知道他的段地址和偏移地址
  2. CPU用8位的中断类型码通过中断向量表找到相应的入口地址
  3. 中断向量就是中断处理程序的入口地址
  4. 中断向量表在内存中保存,对于8086PC机,中断向量表指定放在内存地址的0处,从内存0000:0000到0000:03FF的1024个单元中存放着中断向量表
  5. 一个表项存放一个中断向量,也就是入口地址,一个表项包括段地址与偏移地址,所以一个表项占两个字的空间,高位为段地址,低位为偏移地址。

二十九、中断过程

  1. 取得中断的类型码

  2. 取得类型码N

    pushf 标志寄存器的值入栈

    TF=0,IF=0 设置标志寄存器的第八位TF和第九位的IF的值为0

    push CS

    push IP cs的内容入栈,IP的内容入栈

    (IP)=(N*4)

    (CS)=(N4+2) 从内存地址为中断类型码4和中断类型码×4+2的两个字单元中读取中断处理程序的IP与CS

三十、中断处理程序

  1. 由于CPU随时都有可能检测到中断信息,也就是说,CPU随时都可能执行中断处理程序,所以中断处理程序必须一直存储在内存某段空间中

  2. 常规的步骤:

    保存用到的寄存器

    处理中断

    恢复用到的寄存器

    用iret指令返回

  3. iret指令的功能

    pop IP

    pop CS

    popf

三十一、编程处理0号中断

  1. 当中断0发生的时候,CPU将转去处理中断程序,do0应该放在内存中

  2. 按理来说想要得到一块内存放do0应该向操作系统申请,学习汇编要获得对计算机底层的编程体验,过多的讨论申请内存将会偏离问题的主线。所以直接面向硬件资源

  3. 可以利用中断向量表中的空闲单元来进行存放我们的程序。一般情况下,从0000:0200到0000:02FF的256个字节空间所对应的中断向量表是空的

  4. 相关处理

    向显示缓冲区送字符串

    返回DOS

  5. assume cs:code

    code segment

    start: do0安装程序

    设置中断向量表

    mov ax,4c00h

    int 21h

    do0:显示字符串

    mov ax,4c00h

    int 21h

    code ends

    end start

  6. 编写显示字符串的中断处理程序

    送入到0000:0200处

    将入口地址0000:0200储存在中断向量表的0号表项中

  7. do0的代码是不执行的,作为do0安装程序所要传送的数据,首先安装程序,将代码复制到0:200处,然后设置中断向量表,将do0的入口地址保存在0号表项处。此代码只有在0号溢出的时候才会被执行

  8. 安装

    assume cs:code

    code segment

    start: mov ax,cs

    mov ds,ax

    mov si,offset do0 传送的原始位置

    mov ax,0

    mov es,ax

    mov di,200h 传送的目的位置

    mov cx,offset do0end—offset do0设置传输的长度

    cld 正向传输

    rep movsb

    设置中断向量表

    mov ax,4c00h

    int 21h

    do0:显示字符串

    mov ax,4c00h

    int 21h

    do0end:nop

    code ends

    end start

  9. do0

    因为do0程序随时可能被执行,他也要用到字符串,但不能直接在data段中定义再进行引用,因为执行完成后这段空间会被释放,可能会被别的信息覆盖

    do0:jmp short do0start

    db"overflow!"

    do0start:

    mov ax,cs

    mov ds,ax

    mov si,202h 指向字符串

    mov ax,0b800h

    mov es,ax

    mov di,12*160+36×2 指向显存空间的中间位置

    mov cx,9 设置字符串的长度

    s:mov al,[si]

    mov es:[di],al

    inc si

    add di,2

    loop s 将字符串复制到显存中

    mov ax,4c00h

    int 21h

    do0end:nop

    code ends

    end start

  10. 设置中断向量

    mov ax,0

    mov es,ax

    mov word ptr es:[0*4],200h

    mov word ptr es:[0*4+2],0

三十二、单步中断

  1. CPU在执行完一条指令后,如果检测到标志寄存器的TF位为1则产生单步中断
  2. 单步中断的类型码为1
  3. debug利用了CPU的一种功能,debug提供了单步中断的中断处理程序,功能为显示所有寄存器中的内容后,等待输入命令。使用t指令的时候将TF设为1,使得CPU处在单步中断的方式下,在CPU执行完这条指令后就引发单步中断
  4. 在进入中断处理程序之前将TF设为0

三十三、响应中断的特殊情况

  1. 在执行完向ss寄存器传送数据的指令,即便检测到中断信号,CPU也不会去响应,ss:sp联合指向栈顶,对于他们的设置应该连续完成,因为引发中断的过程,要在栈中压入CS、IP的值
  2. 应该将ss与sp的值进行连续的设置,因为在他们中间的指令也不会受到中断的控制

三十四、int指令

  1. 压入栈的偏移地址是下一条指令的

  2. BIOS和DOS系统所提供的中断例程

  3. 在系统板的ROM中存放一套程序,成为BIOS(基本输入输出系统)

    硬件系统的检测和初始化程序

    外部中断和内部中断的中断例程

    其他和硬件系统相关的中断例程

  4. 操作系统DOS也提供了中断例程,从操作系统的角度看,就是操作系统向程序员提供的编程资料

  5. 和硬件相关的DOS中一般都都调用了BIOS的中断例程

  6. 安装过程,开机后初始化(CS)=0FFFFH,IP=0此处有一条跳转指令,转去执行BIOS中的硬件系统检测和初始化程序

    初始化中断向量,将中断历程的入口地址登记在中断向量表中,程序固化到ROM中所以一直在内存中存在

    调用int 19h进行操作系统的引导,将计算机交由操作系统控制

    DOS启动后将他提供的中断例程装入内存,并建立相应的中断向量

  7. 一般来说,一个供程序员调用的中断历程中往往包括多个子程序,中断例程内部用传递来的参数决定使用哪个子程序。BIOS,DOS提供的中断例程都用ah来传递子程序的编号

三十五、 BIOS和DOS中断例程的应用

  1. bh中页号的含义:在内存地址空间中B8000H~BFFFFH共32KB的空间为80*25彩色字符串的显示缓冲区,一屏的内容在显示缓冲区上共占有4000字节

  2. 显示缓冲区分为8页,每页4KB,显示器可以显示任意一页的内容,一般情况下显示0页的内容

  3. 屏幕的5行3列显示3个红底高亮闪烁绿色的a

    assume cs:code

    code segment

    mov ah,2 调用2号子程序置光标

    mov bh,0 第0页

    mov dh,5 行号

    mov dl,12 列号

    int 10h

    mov ah,9 调用光标位置显示字符

    mov al,'a' 字符

    mov bl,11001010b 颜色属性

    mov bh,0 第0页

    mov cx,3 字符重复的个数

    int 10h

    mov ax,4c00h

    int 21

    code ends

    end

  4. int 21h是DOS提供的中断例程

    4c为程序返回功能

    mov ah,4c 程序返回

    mov al,0 返回值

    int 21h

三十六、端口

  1. 在PC机上和CPU通过总线相连的芯片除各种存储器外,还有以下三种芯片

    各种接口卡(网卡、显卡)上的接口芯片,控制接口卡的工作

    主板上的接口芯片,CPU通过他们对部分外设进行访问

    其他芯片,用来储存相关的系统信息,或进行相关的输入输出处理

  2. 这些芯片中都有一组可以由CPU进行读写的寄存器,他们在物理上可能处于不同的芯片上,但又有共同特点:和CPU总线相连,这种连接是通过他们所在的芯片进行的,CPU对他们进行读写的时候都通过控制线向他们所在的芯片发出端口读写命令

  3. 从CPU的角度将这些寄存器都当作端口,对他们进行统一的编址,建立一个统一的端口地址空间

  4. CPU可以直接读写三个地方的数据

    CPU的内部寄存器

    内存单元

    端口

  5. 端口的读写

    端口地址和内存地址一样通过地址总线来进行传送,在PC系统中,CPU最多可以定位64KB的不同端口,端口范围为0~65535

    对端口的读写不能用mov,push,pop等内存读写指令,端口的读写指令只有两条:in,out

  6. 只能用al,ax来存放端口中读入的数据或要发送到端口中的数据

  7. CMOS RAM芯片有一个实时钟和128个存储单元的RAM存储器,该芯片靠电池供电,关机后时钟仍然可以工作,RAM中的内容也不丢失,时钟占0~0dh单元来储存时间信息,其余大部分用来保存系统配置信息,供系统启动时BIOS程序的读取。BIOS也提供相关的程序。芯片有两个端口70h(地址端口写入读取单元地址)71h(数据端口读出)

  8. shl和shr指令

    shl左移指令,将一个寄存器或内存单元中的数据向左位移,最后一位写入到CF中,最低位用0进行填充。如果移动数位大于一的时候要将数位放在cl中mov cx,3

    shl al,cl

  9. CMOS RAM中存放当前的时间:年,月,日,时,分,秒。这6个信息长度为1字节。秒:0,分:2,时:4,日:7,月:8,年:9

    以BCD码的形式进行存放

    mov al,8

    out 70h,al

    in al,71h

    将BCD码表示的月份以十进制的形式显示到屏幕上

    BCD码值=十进制数码值,BCD码值+30h=十进制对应的ASCAII码

    从CMOS RAM读出的一个字节,包含两个BCD码表示的两位十进制数

    assume cs:code

    code segment

    start: mov al,8

    out 70h,al

    in al,71h 读取月份的数值

    mov ah,al 将数据复制到高位寄存器中

    mov cl,4

    shr ah,cl 将ah的值用来表示十位的数值

    and al,00001111b 设置为个位数值

    add ah,30h

    add al,30h 转换为十进制数

    mov bx,0b800h

    mov es,bx

    mov byte ptr es:[160*12+40×2],ah 显示月份的十位数码

    mov byte ptr es:[160*12+40×2+2],al 显示月份的个位数码

    mov ax,4c00h

    int 21h

    code ends

    end start

三十七、外中断

  1. CPU通过端口和外部设备进行联系

  2. 外设输入的到达,相关芯片向CPU发出相应的中断信息。CPU在执行完当前的指令后,可以检测到发来的中断信息,引发中断过程处理外设的输入

  3. 外中断源可分为可屏蔽中断和不可屏蔽中断

    可屏蔽CPU可以不响应外界的中断。

    取中断类型码,将标志寄存器入栈,IF=0,TF=0,CS、IP入栈···

    将IF置为0,在进入中断处理程序后禁止其他的可屏蔽中断sti,IF=1、cli,IF=0

  4. 不可屏蔽中断是CPU必须响应的,类型码固定为2

  5. 键盘上的一个键相当于一个开关,键盘中有一个芯片对键盘上的每一个键的开关状态进行扫描,按下一个键的时候,芯片就会产生一个扫描码,扫描码说明了按下的键在键盘中的位置。扫描码被送入主板相关接口芯片的寄存器中,该寄存器的端口为60h,松开的时候也产生一个扫描码,说明了松开的键在键盘上的位置。产生的扫描码也被送入到60H端口中

  6. 一般将按下一个键产生的叫做通码,松开产生的叫做断码,扫描码的长度为一个字节,通码第7位为0,断码的第7位为1.断码=通码+80h

  7. 输入到达60h端口的时候,会发出中断类型码为9的可屏蔽中断信息

    读出60h端口中的扫描码

    如果是字符键的扫描码,将他和对应的ASCAII送入到内存中BIOS键盘缓冲区,如果是控制键如控制键和切换键,则转换为状态字节(用二进制位记录控制键和切换键状态的字节)写入到内存中存储状态字节的单元

    对键盘系统进行相关的控制,比如向相关芯片发出应答信息

    BIOS用于存放int 9中断例程接收的键盘输入的内存区,可以存储15个键盘输入,因为除了接收扫描码以外,还要产生对应的字符码,一个键盘输入用一个字的空间进行存放

  8. 0040:17单元存储键盘状态字节,记录了控制键和切换键的状态

    0:左Shift状态,1表示按下

    1:右Shift状态,1表示按下

    2:Ctrl状态,1表示按下

    3:Alt状态,1表示按下

    4:ScrollLock,1表示Scroll指示灯亮

    5:NumLock,1表示小键盘输入的是数字

    6:CapsLock,1表示输入大写字母

    7:Insert,1表示处于删除状态

三十八、直接定址表

  1. 标号仅表示内存单元的地址

  2. 一种标号不但表示内存单元的地址,还表示内存单元的长度,即表示了此标号处的单元,是一个字节单元,还是字单元,还是双字单元

  3. a db 1,2,3,4,5,6,7,8

    b dw 0

  4. 可以用a[i]的形式对其中的数据进行索引

  5. inc b相当于inc word ptr cs:[8]

  6. b代表一个内存单元

  7. 在代码段直接使用数据标号访问数据,需要用伪指令assume将标号所在的段和段寄存器联系起来,否则在编译的时候,无法确定标号的段地址在哪一个段寄存器中

  8. c dw a,b储存的是两个数据型为标号a,b的偏移地址

  9. c dd a,b存储的为a的偏移地址和段地址、标号b的偏移地址和段地址

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值