yundi 发表于 2016-1-27 14:36:42

第13章检测实验及笔记

两个简单问题,选做一个,记住复制代码和改写中断向量表的固定步骤

;中断7ch的中断例程
;功能:将0结尾字符串改为大写
;参数:ds:si指向串首
;返回值:无
assume cs:code
code segment
start:
;复制代码
        mov ax,cs
        mov ds,ax
        mov si,offset todo
       
        mov ax,0h
        mov es,ax
        mov di,200h
       
        mov cx,offset todoend - offset todo
        cld
        rep movsb
;改写中断向量表
        mov ax,0
        mov ds,ax
        mov word ptr ds:,200h
        mov word ptr ds:,0
       
        mov ax,4c00h
        int 21h
;中断处理
        todo:
                push cx
                mov ch,0
                s:
                mov cl,ds:
                jcxz return
                and cl,11011111b
                mov ds:,cl
                inc si
                jmp s
        return:
                pop cx
                iret
        todoend:
                nop
code ends
end start

yundi 发表于 2016-1-27 14:51:05

稍难一点的,难点在于中断处理程序如何改变父程序
;功能:用7ch中断例程完成loop指令的功能
assume cs:code
code segment
        start:
        ;复制
        mov ax,cs
        mov ds,ax
        mov si,offset todo
       
        mov ax,0
        mov es,ax
        mov di,0200h
       
        mov cx,offset todoend - offset todo
       
        cld
        rep movsb
       
        ;安装
        mov ax,0
        mov ds,ax
        mov word ptr ds:,0200h
        mov word ptr ds:,0h
        mov ax,4c00h
        int 21h
               
                todo:
                ;loop的原理:1.(cx)=(cx)-1 2.如果(cx)<>0跳回,=0继续
                ;这段代码要做的:
                ;1.(cx)=(cx)-1
                sub cx,1
                ;2.判断
                ;2.1为零继续
                jcxz return
                ;2.2不为零跳回。如何找到调用父程序s标号的段和偏移?
                ;在int的时候,cs,ip入了栈,所以可以改写栈中数据,等中断结束回到父程序时,依据被改写的cs:ip实现跳回
                ;(不是从栈中将cs:ip取出来jmp!)
                ;当前ss:正是ip的值
                add ,bx;偏移改为指向s
                return:
                        iret               
                todoend:nop
code ends
end start

书上没有直接用,而是用中转,更安全

yundi 发表于 2016-1-28 10:24:53

本帖最后由 yundi 于 2016-1-28 12:54 编辑

BIOS,DOS中断

先不用中断做个练习
;在屏幕5行12列显示3个红底高亮闪烁绿色的'a'
;参数dh=行号,dl=列号,al=字符,cx=重复次数

assume cs:code
code segment
start:
        mov dh,5
        mov dl,12
        mov al,'a'
        mov cx,3 ;参数赋值
       
        call showa;调子程序
        mov ax,4c00h
        int 21h
showa:
        push ax
        mov ax,0b800h
        mov ds,ax;段0b800h
        mov bx,0
        mov al,160
        mul dh;160*dh
        add bx,ax
        mov al,2
        mul dl;2*dl
        add bx,ax;偏移160*行+2*列
        pop ax;
s:        mov byte ptr ds:,al
        mov byte ptr ds:,11001010b
        add bx,2
        loop s
        ret       
code ends
end start

用上提供的中断例程,变得简单多了
;在屏幕5行12列显示3个红底高亮闪烁绿色的'a'
assume cs:code
code segment
start:
        ;定位光标
        mov ah,2
        mov bh,0
        mov dh,5
        mov dl,12
        int 10h
        ;显示
        mov ah,9
        mov al,'a'
        mov bl,11001010b
        mov bh,0
        mov cx,3
        int 10h
       
        mov ax,4c00h
        int 21h

code ends
end start
页: [1]
查看完整版本: 第13章检测实验及笔记