读书笔记:汇编语言 第三版 王爽 清华出版社 章十一 章十二 章十三 章十四 章十五

第十一章 标志寄存器
    11.0 概述
        作用
            存储部分指令的部分执行结果
            作为部分指令的执行参数
            用来控制CPU的相关工作方式
        8086CPU标志寄存器
            有十六个位
            存储的信息,称为程序状态字(PSW)
            标志寄存器(flag),是按位起作用的
                其他数据寄存器,是整体起作用的
            结构
                15  14  13  12  11  10  9  8    7   6   5   4   3   2   1   0
                                OF  DF  IF  TF  SF  ZF      AF      PF      CF
        使用指令时,注意指令对标志寄存器的影响
    11.1 ZF标志
        Zero Flag
        变化指令
            算术逻辑运算指令
                add、sub、mul、div
                inc、or、and
        变化规律
            (ZF) = 指令结果==0
        结果为0吗?
    11.2 PF标志
        Parity Flag
        (PF) = 指令结果的二进制1位数量==偶数
        结果为偶数个1吗?
    11.3 SF标志
        Sign Flag
        (SF) = 指令结果最高位==1
        结果为负吗?
    11.4 CF标志
        Carry Flag
        用于无符号运算
        (CF) = 指令结果包含进位或借位
            加法中可能出现进位
            减法中可能出现借位
        结果有进位借位吗
    11.5 OF标志
        Overflow Flag
        用于有符号运算
        溢出现象,运算结果超出机器表示范围
            8位,-128~127
            16位,-32768~32767
            加法溢出
                正极大+正极大,过大而负
                负极小+负极小,过小而正
            减法溢出
                正极大-负极小,过大而负
                负极小-正极大,过小而正
        (OF) = 指令结果发生溢出
        结果有溢出吗
        例子1
            mov al, 0f0h
            add al, 88h
            看作无符号运算,有进位(CF)=1
            看作有符号运算,有溢出(OF)=1
        例子2
            mov al, 0f0h
            add al, 78h
            看作无符号运算,有进位(CF)=1
            看作有符号运算,无溢出(OF)=0
    11.6 adc指令
        名称,带进位加法
        格式,adc p1, p2
        行为,p1 = p1 + p2 + cf
        目的,用于实现任意位数的加法
            低位的普通相加,或者cf为0的带进位加法
            高位的带进位加法
        例子
            ; name, add128
            ; function, two 128 bits data add
            ; parameters
            ;    p1, ds:si, low byte low address
            ;    p2, ds:di, low byte low address
            add128:
                push ax
                push cx
                push si
                push di

                sub ax, ax            ; set cf=0

                mov cx, 8
            add128_s:
                mov ax, [si]
                adc ax, [di]
                mov [si], ax
                inc si
                inc si
                inc di
                inc di
                loop add128_s

                pop di
                pop si
                pop cx
                pop ax
                ret
    11.7 adc指令
        名称,带借位减法
        格式,sbb p1, p2
        行为,p1 = p1 - p2 - cf
        目的,用于实现任意位数的减法
            低位的普通相减,或者cf为0的带借位减法
            高位的带借位减法
    11.8 cmp指令
        比较指令,相当于不存结果的减法指令,会影响标志寄存器
            cmp p1, p2
        看作无符号数比较
            即无符号数减法
            zf = 1               p1 == p2
            zf = 0               p1 != p2
            cf = 1               p1 <  p2
            cf = 0               p1 >= p2
            cf = 0 and zf = 0    p1 >  p2
            cf = 1 or  zf = 1    p1 <= p2
        看作有符号数比较
            即有符号数减法
            of = 0 and sf = 0    p1 >= p2
            of = 0 and sf = 1    p1 <  p2
            of = 1 and sf = 0    p1 <  p2
            of = 1 and sf = 1    p1 >  p2
    11.9 检测比较结果的条件转移指令
        条件转移指令
            属于短转移,[-128, 127]
            行为,条件触发时转移,即修改IP
            常与影响条件的指令配合使用,如cmp、sub、add等
        jcxz,检查cx是否为0
        基于无符号比较结果的条件转移指令
            je      ==      zf=1                equal
            jne     !=      zf=0                not equal
            jb      <       cf=1                below
            jnb     >=      cf=0                not below
            ja      >       cf=0 and zf=0       above
            jna     <=      cf=1 or  zf=1       not above
        基于有符号比较结果的条件转移指令
            je      ==      zf=1                equal
            jne     !=      zf=0                not equal
            jl      <       (of=0 and sf=1) or (of=1 and sf=0)        less
            jnl     >=      of=0 and sf=0       not less
            jg      >       of=1 and sf=1       greater
            jng     <=                          not greater
        检查单个标志位
            jz              zf=1
            jnz             zf=0
            js              sf=1
            jns             sf=0
            jo              of=1
            jno             of=0
            jp              pf=1
            jnp             pf=0
            jc              cf=1
            jnc             cf=0
        编程时注意转移语义
            逻辑语义,
                条件C成立,则执行A
            C语言
                与自然描述一致
                    以执行为描述中心
                if (C) A;
            汇编语言
                与自然描述相反
                    以转移为描述中心
                    反条件成立,则转移
                jmp !C
                A
        例子,统计data段中数值为8的字节的个数
            data segment
                db 8,11,8,1,8,5,63,38
            data ends
            code segment
            start:
                mov ax, data
                mov ds, ax
                mov bx, 0
                mov ax, 0
                mov cx, 0
            s:  cmp byte ptr [bx], 8
                jne next
                inc ax
            next:
                inc bx
                loop s

                mov ax, 4c00h
                int 21h
            code ends
    11.10 DF标志和串传输标志
        rep movsb
            move serial bytes
            从ds:[si]到es:[di],DF方向传输cx个字节
            相当于
                s:  mov byte ptr es:[di], ds:[si]
                    若DF为0
                        inc si
                        inc di
                    若DF为1
                        dec si
                        dec di
                    loop s
        rep movsw
            move serial words
            从ds:[si]到es:[di],DF方向传输cx个字
            相当于
                s:  mov word ptr es:[di], ds:[si]
                    若DF为0
                        add si, 2
                        add di, 2
                    若DF为1
                        sub si, 2
                        sub di, 2
                    loop s
        DF
            指定si和di的增长方向,0正1负
            std指令,set df,df=1
            cld指令,clear df,df=0
        例子,复制字符串到随后空间中
        data segment
            db 'welcome to masm!'
            db 16 dup (0)
        data ends
        code segment
            mov ax, data
            mov ds, ax
            mov es, ax
            mov si, 0
            mov di, 16
            mov cx, 16
            cld
            rep movsb
        code ends
    11.11 pushf和popf
        pushf,标志寄存器入栈,push flag
        popf,出栈到标志寄存器,pop flag
    11.12 标志寄存器在Debug中的表示
        对应关系
            xx xx xx xx xx xx xx xx
            OF DF    SF ZF    PF CF
        标志表示
            标志     1   0
            of      OV  NV
            sf      NG  PL
            zf      ZR  NZ
            pf      PE  PO
            cf      CY  NC
            df      DN  UP
    11.13 实验11 编写子程序
        assume cs:code
        data segment
            db "Beginner's All-purpose Symbolic Instruction Code.", 0
        data ends
        code segment
        begin:
            mov ax, data
            mov ds, ax
            mov si, 0
            call letterc

            mov ax, 4c00h
            int 21h
        letterc:
            push cx
            push si
            mov ch, 0
        letterc_s:
            mov cl, [si]
            jcxz letterc_ret
            and cl, 11011111b
            mov [si], cl
            inc si
            loop letterc_s
        letterc_ret:
            pop si
            push cx
            ret
        code ends
        end begin

第十二章 内中断
    12.0 概述
        CPU的中断能力
            CPU执行完一条指令后,若检测到一种特殊信息(外部发送或内部产生),则立即对其进行处理
            这种特殊信息,称为中断信息
                中断信息,是一种逻辑上的说法
                    它是对硬件产生的事件的同一描述
                中断信息,要求CPU立即进行处理,并提供必要的参数
                中断信息,可来自CPU外部和内部
            中断,暂停当前,处理突发
    12.1 内中断的产生
        CPU发生如下情况时,将产生对应的中断信息
            除法错误,如商溢出    0
            单步执行            1
            执行into指令        4
            执行int指令         参数决定
        8086CPU用中断类型码标识中断信息的类型和来源
            中断类型码,为一个字节,可表示256种中断信息来源
            中断源,中断信息的来源,即产生中断信息的事件
    12.2 中断处理程序
        用来处理中断信息的程序,称为中断处理程序
        一般而言,中断类型不同,中断处理程序不同
    12.3 中断向量表
        中断向量表
            中断向量的列表
            中断处理程序入口地址的列表
        CPU通过中断类型码N,定位到中断处理程序入口地址的存储位置(4*N),获取入口地址
            中断类型码,0~255
            中断向量表,0~1023(3ff)
                在一个中断向量中,低字存偏移地址,高字存段地址
    12.4 中断过程
        获得中断类型码
        标志寄存器入栈
        TF、IF置为0
        CS和IP入栈
        使用中断向量,设置IP(4*N)和CS(4*N+2)
    12.5 中断处理程序和iret指令
        由于CPU随时可以执行中断请求,故中断向量表和中断处理程序需要一直存储在内存中
        中断处理程序的编写,与子程序编写类似
            保存用到的寄存器
            处理中断
            恢复用到的寄存器
            iret
                IP和CS出栈
                    pop IP
                    pop CS
                标志寄存器出栈
                    popf
    12.6 除法错误中断的处理
        除法溢出
        代码
            mov ax, 1000h
            mov bh, 1
            div bh
        显示信息
            Your program caused a  divide overflow error.
            If the program persists, contact your program vendor.
    12.7 编程处理0号中断
        编写中断处理程序
            显示字符串 "overflow!"
        安装中断处理程序
            程序存放空间
                由于我们在操作系统上使用计算机,所有硬件资源都在操作系统管理之下
                    使用内存资源,需要向操作系统申请
                    但过多讨论内存申请,将偏离主题
                    我们学习汇编的目的,在于获得底层编程的体验,尽可能的直接面向硬件资源
                8086一共支持256个中断类型,内存0~3ffh用于存放中断向量表,但许多空间都是空的
                中断向量表是PC系统最重要的内存区,DOS系统和其他应用程序不会随意使用这段空间
                可以使用200h~2ffh这段空间
                    中断向量为空
                    操作系统和其他应用程序不会使用
            设置中断向量表
                将程序的入口地址,放入中断向量表中
                    根据中断类型码,定位表中的项空间
                    偏移地址在低字,段地址在高字
        程序框架
            assume cs:code
            code segment
            start:
                do0安装程序
                设置中断向量表
                mov ax, 4c00h
                int 21h
            d0:
                显示字符串"overflow!"
                mov ax, 4c00h
                int 21h
            code ends
            end start
    12.8 安装
        "-"是编译器可识别的运算符号,用来进行两个常数的减法
        代码
            start:
                ; d0安装程序
                mov ax, cs
                mov ds, ax
                mov si, offset do0
                mov ax, 0
                mov es, ax
                mov di, 200h
                mov cx, offset do0_end - offset do0
                cld
                rep movsb

                设置中断向量表
                mov ax, 4c00h
                int 21h
            do0:
                显示字符串"overflow!"
                mov ax, 4c00h
                int 21h
            do0_end:
                nop
    12.9 do0
        中断程序,包含指令和数据,需要一起并长期存放在内存中
            在当前情况下,可以将数据放入中断程序中
        代码
            do0:
                jmp short do0_start 
                db 'overflow!'
            do0_start:
                mov ax, cs
                mov ds, ax
                mov si, 202h
                mov ax, 0b800h
                mov es, ax
                mov di, 12*160+36*2
                mov cx, 9
            do0_s:
                mov al ds:[si]
                mov es:[di], al
                add di, 2
                inc si
                do0_s

                mov ax, 4c00h
                int 21h
            do0_end:
                nop
    12.10 设置中断向量
        代码
            mov ax, 0
            mov es, ax
            mov word ptr es:[4*0], 200h
            mov word ptr es:[4*0+2], 0
    12.11 单步中断
        CPU执行完一条指令后,若检查到TF为1,则产生单步中断,中断类型码为1
            注意中断过程中,TF和IF被置为0,避免了中断递归、
        Debug利用单步中断实现T命令
            Debug提供了单步中断的中断处理程序
                功能为显示寄存器内容,等待输入
            执行t命令时,将TF置为1,使得CPU执行完单条指令后引发单步中断
    12.12 相应中断的特殊情况
        在有些情况下,即便CPU检测到中断,也不会响应
        中断过程中需要向栈中保存数据,为了保证栈顶地址的一直有效性
            向ss段寄存器传送数据后,会继续执行后一条指令,不会被中断
            向ss段寄存器传送数据后,应该是传送sp偏移地址
    12.13 编写0号中断的处理程序

第十三章 int指令
    13.0 概述
        当有需要立即处理的事情时,将产生中断信息,CPU检测到中断信息后,将引发中断过程
        中断信息可来自CPU的内部和外部
        int指令引发的是内中断
    13.1 int指令
        格式,int N
        行为,引发中断过程,中断类型码为N,后转去执行中断处理程序
            中断处理程序,简称为中断例程
        int指令与call指令
            相同,调用一段程序
            不同
                call,普通函数调用,属于静态绑定,一般用于调用内部子程序
                int,虚函数调用,属于动态绑定,一般用于调用外部程序
                    属于变化度分离,程序的调用和实现
    13.2 编写供应用程序调用的中断例程
        编写、安装中断7ch的中断例程
            功能,求一个字的平方
            参数,ax
            返回值,ax存放结果低16位,dx存放结果高16位
            例子,求2*3456^2
                mov ax, 3456
                int 7ch
                add ax, ax
                adc dx, dx
                mov ax, 4x00h
                int 21h
            代码,int7c.asm
                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 handler_end - offset handler
                    cld
                    rep movsb

                    mov ax, 0
                    mov es, ax
                    mov word ptr es:[4*7ch], 200h
                    mov word ptr es:[4*7ch+2], 0
                    mov ax, 4c00h
                    int 21h
                handler:
                    mul ax
                    iret
                handler_end:
                    nop
                code ends
                end start
    13.3 对int、iret和栈的深入理解
        用7ch中断例程完成loop指令的功能
        应用代码,在屏幕打印80个'!'
                mov ax, 0b800h
                mov es, ax
                mov di, 160*12

                mov bx, offset s - offset se
                mov cx, 80
            s:  mov byte ptr es:[di], '!'
                add di, 2
                int 7ch

                mov ax, 4c00h
                int 21h
        中断例程
            lp: dec cx
                jcxz lp_ret
                push sp
                mov bp, sp
                add [bp+2], bx
                pop sp
            lp_ret:
                iret
    13.4 BIOS和DOS所提供的中断例程
        在主板的ROM中,存放着一套程序,称为BIOS,包括
            硬件系统的检测和初始化程序
            外部中断和内部中断的中断例程
            用于对硬件设备进行I/O操作的中断例程
            其他和硬件系统相关的中断例程
        操作系统DOS也提供了中断例程,DOS的中断例程就是操作系统向程序员提供的编程资源
        BIOS和DOS提供的中断例程中包含了许多子程序,为编程提供常用功能
        和硬件设备相关的中断例程中,一般都调用了BIOS的中断例程
    13.5 BIOS和DOS中断例程的安装过程
        1. 开机后,CPU加电,初始化(CS)=FFFF,(IP)=0,自动从FFFF:0开始执行程序
            FFFF:0处是一条跳转指令,转去执行BIOS中的硬件系统检测和初始化程序
        2. 初始化程序,将建立BIOS支持的中断向量
            注意,安装BIOS中断例程时,只需要设置中断向量表,因为中断例程固化在ROM中,一直处于内存中
        3. 硬件系统检测和初始化程序完成后,调用int 19h进行操作系统的引导
            从此计算机交由操作系统控制
        4. DOS启动后,会将支持的中断例程装入内存,并设置中断向量表
    13.6 BIOS中断例程应用
        int 10h中断例程
            BIOS提供
            包含多个子程序,与屏幕输出有关
        设置光标
            mov ah, 2    ; sub program id, set cursor
            mov bh, 0    ; page index
            mov dh, 5    ; row index
            mov dl, 12   ; column index
            int 10h
        在光标处显示字符
            mov ah, 9
            mov al, 'a'  ; symbol which will be display
            mov bl, 7    ; property code
            mov bh, 0    ; page index
            mov cx, 3    ; repeat count
            int 10h
    13.7 DOS中断例程应用
        int 21h中断例程,DOS提供
        程序返回
            mov ah, 4c   ; program return
            mov al, 0    ; return value
            int 21h
        在光标处显示字符串
            ds:dx指向$结尾的字符串
            mov ah, 9
            int 21h
    13.8 编写、应用中断例程

第十四章 端口
    14.0 概述
        和CPU通过总线相连的芯片种类
            存储器芯片,RAM、ROM等
            接口卡上接口芯片,它们会控制接口卡工作
            主板上的接口芯片,用于控制部分外设
            其他芯片,用来存储相关的系统信息,或进行相关的输入输出处理
        在后三种芯片中,都有一对可由CPU读写的寄存器
        这些成对的寄存器
            都和CPU总线相连,通过芯片进行连接的
            被CPU读写时,都是通过控制线向其芯片发送端口读写命令的
        从CPU的角度,将这些寄存器都当作端口,并进行统一的编址,建立了一个统一的端口地址空间
        CPU可直接访问的位置
            CPU内部寄存器
            内存地址空间
            端口地址空间
    14.1 端口的读写
        端口所在芯片和CPU通过总线相连,端口地址通过地址总线来传输
        在PC系统中,CPU最多定位64KB个不同端口,端口地址范围为[0, 65535]
        内存读操作
            CPU在地址线上写地址信息
            CPU在控制线上写内存读命令,选中存储器芯片
            存储器芯片向数据线上写数据
        端口读操作
            CPU在地址线上写地址信息
            CPU在控制线上写端口读命令,选中端口芯片
            端口芯片向数据线上写数据
        端口访问命令
            读,in al/ax, idata/dx
                端口号
                    [0~255],使用立即数
                    [256~65535],使用dx
            写,out idata/dx, al/ax
    14.2 CMOS RAM芯片
        包含一个实时钟和一个RAM(128字节)
        通过电池供电,关机后信息不丢失
        RAM使用
            实时钟占用[0~0dh],保存时间信息
            其余大部分单元用于保存系统配置信息
                供系统启动时BIOS读取
                BIOS提供程序配置CMOS RAM中的系统信息
        有两个端口
            地址端口,70h
            数据端口,71h
            使用步骤
                写地址端口
                读写数据端口
    14.3 shl和shr指令
        shl 寄存器/内存单元, 1/cl
            逻辑左移,低位补0,移出位存于CF
            数据左移,相当于*2
        shr 寄存器/内存单元, 1/cl
            逻辑右移,高位补0,移出位存于CF
            数据右移,相当于/2
    14.4 CMOS RAM中存储的时间信息
        位置,秒0分2时4日7月8年9
        格式,BCD码
    15.4 实验14 访问CMOS RAM
        assume cs:code

        data segment
            db 'yy/mm/dd hh:MM:ss$'
        d_pos:
            db 9,8,7,4,2,0
        data ends

        stack segment stack
            db 160 dup (0)
        stack ends

        code segment
        start:
            mov ax, data
            mov ds, ax
            mov bx, 0
            mov si, offset d_pos
            mov cx, 6
        s:
            mov al, [si]
            out 70h, al
            in al, 71h
            call convert
            add bx, 3
            inc si
            loop s

            mov ah, 2
            mov bh, 0
            mov dh, 12
            mov dl, 30
            int 10h

            mov dx, 0
            mov ah, 9
            int 21h

            mov ax, 4c00h
            int 21h
        
        convert:
            push ax
            push cx 
            mov ah, al
            mov cl, 4
            shr ah, cl
            and al, 0fh
            mov byte ptr [bx], ah
            mov byte ptr [bx+1], al
            pop cx
            pop ax
            ret
        code ends

        end start

第十五章 外中断
    15.1 接口芯片和端口
        PC系统的接口卡和主板上,有各种的外设接口芯片
        这些外设接口芯片中有一些寄存器,CPU将这些寄存器当作端口进行访问
    15.2 外中断信息
        外中断源
            可屏蔽中断
                CPU可不响应的外中断
                CPU检测到可屏蔽中断时
                    若IF为1,则响应
                    若IF为0,则不响应
                可屏蔽中断引发的中断过程
                    与内中断引发的中断过程类似
                    仅"取中断类型码N"的实现不同
                        可屏蔽中断信息,来自于CPU外部,中断类型码通过数据总线传入CPU
                        内中断的中断类型码,在CPU内部产生
                中断过程中将IF置为0,是为了禁止可屏蔽中断
                    在设置中断向量表时,也需要禁止可屏蔽中断
                        避免在仅设置了段地址时,出现可屏蔽中断,导致CPU执行错误指令
                IF设置
                    sti,设置IF为1
                    cli,设置IF为0
            不可屏蔽中断
                CPU必须响应的外中断
                不可屏蔽中断的中断类型码,固定为2,故中断过程不需要取中断类型码
        几乎所有外设引发的外中断,都是可屏蔽中断
        不可屏蔽中断是在系统中有必须处理的紧急情况
    15.3 PC机键盘的处理过程
        键盘的输入
            键盘上的键,相当于一个开关,键盘中有一个芯片,会对所有键的开关状态进行扫描
            按下一个键,芯片产生一个扫描码,称为通码,扫描码被送入主板上相关接口芯片的寄存器中,端口号为60h
            松开一个键,芯片产生一个扫描码,称为断码
            扫描码,一个字节长
            同一键,通码+80h=断码
        引发9号中断
            键盘的输入到达60h端口后,相关的芯片会向CPU发送9号可屏蔽中断的中断信息
        执行9号中断例程
            主要工作
                读取60h端口的扫描码
                扫描码
                    是字符键,将扫描码和字符码送入内存中BIOS键盘缓冲区
                        BIOS键盘缓冲区,可存储15个键盘输入
                        一个键盘输入,为一个字,高位字节为扫描码,低位字节为字符码
                    是控制键(Ctrl)或切换键(CapsLock),将其转变为状态字节写入内存
                        40:17存储键盘状态字节,记录了控制键和切换键的状态
                        状态字节的位心理系
                            0,右shirt,按下为1
                            1,左shirt,按下为1
                            2,Ctrl,按下为1
                            3,Alt,按下为1
                            4,ScrollLock,Scroll灯亮为1
                            5,Numlock,Num灯亮为1
                            6,CapsLock,Caps灯亮为1
                            7,Insert,为1表示删除状态
                对键盘系统进行控制,如发送应答信息
    15.4 编写int9中断例程
        不完整地编写键盘中断例程,因为需要处理一些键盘细节,只需在自定义的中断例程中调用BIOS的中断例程
        任务
            在屏幕中依次显示"a"~"z"
            可以让人看清
            在显示过程中,按下Esc键,则改变显示颜色
        代码
            assume cs:code

            stack segment stack
                db 128 dup (0)
            stack ends

            data segment
                db 4 dup (0)
            data ends

            code segment
            start:
                ; modify int9 handler
                mov ax, 0
                mov es, ax
                mov ax, data
                mov ds, ax
                mov ax, es:[9*4]
                mov ds:[0], ax
                mov ax, es:[9*4+2]
                mov ds:[2], ax
                cli
                mov word ptr es:[9*4], offset int9
                mov es:[9*4+2], cs
                sti

                ; display symbol
                mov ax, 0b800h
                mov es, ax
                mov cx, 26
                mov bl, 'a'
                mov ax, 0
                mov dx, 100h
            s:  mov es:[12*160+40*2], bl
                inc bl
                call delay
                loop s
                
                ; recover int9 handler
                mov ax, 0
                mov es, ax
                cli
                mov ax, ds:[0]
                mov es:[9*4], ax
                mov ax, ds:[2]
                mov es:[9*4+2], ax
                sti

                mov ax, 4c00h
                int 21h
            delay:
                push ax
                push dx
                push cx
            delay_s:
                sub ax, 1
                sbb dx, 0
                mov cx, ax
                or  cx, dx
                jcxz delay_ret
                jmp short delay_s
            delay_ret:
                pop cx
                pop dx
                pop ax
                ret
            int9:
                push ax
                push es

                in al, 60h

                pushf
                call dword ptr ds:[0]

                cmp al, 1
                jne int9_ret
                mov ax, 0b800h
                mov es, ax
                inc byte ptr es:[12*160+40*2+1]

            int9_ret:
                pop es
                pop ax
                iret
            code ends

            end start
    15.5 安装新的int9中断例程
        任务
            按F1,改变当前屏幕颜色
        代码
            assume cs:code

            stack segment stack
                db 128 dup (0)
            stack ends

            code segment
            start:
                mov ax, cs
                mov ds, ax
                mov si, offset int9
                mov ax, 0
                mov es, ax
                mov di, 204h
                mov cx, offset int9_end - offset int9
                cld
                rep movsb
                
                mov ax, es:[9*4]
                mov es:[200h], ax
                mov ax, es:[9*4+2]
                mov es:[202h], ax
                cli
                mov word ptr es:[9*4], 204h
                mov word ptr es:[9*4+2], 0
                sti

                mov ax, 4c00h
                int 21h
            int9:
                push ax
                push es
                push bx
                push cx

                in al, 60h

                pushf
                call dword ptr cs:[200h]

                cmp al, 3bh
                jne int9_ret
                mov ax, 0b800h
                mov es, ax
                mov bx, 1
                mov cx, 80*25
            int9_s:
                inc byte ptr es:[bx]
                add bx, 2
                loop int9_s

            int9_ret:
                pop cx
                pop bx
                pop es
                pop ax
                iret
            int9_end:
                nop
            code ends

            end start
    15.6 安装新的int9中断例程
    15.7 指令系统总结
        数据传送指令
            mov, push, pop, pushf, popf, xchg
        算术运算指令
            add, sub, adc, sbb, inc, dec, cmp, imul, idiv, aaa
        逻辑指令
            and, or, not, xor, test, shl, shr, sal, sar, rol, ror, rcl, rcr
        转移指令
            jmp
            jcxz, je, jb, ja, jnb, jna
            loop
            call, ret, retf
            int, iret
        处理机控制指令
            cld, std
            cli, sti
            nop, clc, cmc, stc, hlt, wait, esc, lock
        串处理指令
            movsb, movsw, cmps, scas, lods, stos
            和rep, repe, repne等前缀指令配合使用

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值