汇编语言-课程设计2


;===============OVERVIEW================

DOG.exe 中 装载了程序 installer1, installer2, installer3, booter, newint, mainsub, set_ui, wait_choice, f1, f2, f3, f4, f5, show_str;

mainsub 拥有五个功能函数 f1~f5, 两个子函数 set_ui & wait_choice, 一个通用的 show_str;

installer1 将 booter 装入软盘1号扇区, installer2 将 newint 装入软盘2号扇区, installer3 将 mainsub 装入软盘3~6号扇区;

booter 负责用 newint 替换旧的 BIOS int 9h 中断例程, 将 mainsub 安装, 并将几个重要的地址记录在地址0:200h处. Jump 至 mainsub;

newint 位于0:200h-0:400h, 但前 10h bytes 留空, 用来给 booter 写入几个函数的入口地址. newint 在旧的 int 9h 功能的基础上增加了对 F1 与 ESC 键的特殊处理. Press ESC to jump to mainsub again;

mainsub 位于7e0h:0. 开辟一块栈之后, call set_ui and then jump to wait_choice;

show_str 功能是 show string;

set_ui 功能是 set UI;

wait_choice 用于触发 f1~f5;

注意: 需要想出一个 idea(我的源程序中有具体方法), 解决按下 esc 之后键盘缓冲区如何清空的问题.


;=======IMPLEMENTATION & SOURCE=========

嘉心糖的汇编语言课程设计-For Miss.JiaRan_哔哩哔哩_bilibili汇编语言-课程设计2耗时六天半?(五天在摸鱼8086 yyds !https://www.bilibili.com/video/BV15L411w7kU?share_source=copy_web

assume cs:code,ss:stack

stack segment
    db 32 dup (0)
stack ends

code segment
    start:
        mov ax,stack
        mov ss,ax
        mov sp,32             ;SS:SP=stack:32

        call installer1
        call installer2
        call installer3

        mov ax,4c00h
        int 21h
;XXXXXXXXXXXXXXXXXXXXXThree installer-functions are here.XXXXXXXXXXXXXXXXXXXXXXX
installer1:
    ;boot.exe in 1
    
    push bx
    push es
    push ax
    push cx
    push dx

    mov bx,seg first_installed
    mov es,bx
    mov bx,offset first_installed   ;es:bx -> first_installed
    
    mov ah,3    ;write
    mov al,1    ;amount
    mov ch,0
    mov cl,1    ;number:1
    mov dx,0
    int 13h

    pop dx
    pop cx
    pop ax
    pop es
    pop bx
    ret
;-------------------------------------------------------------------------------
installer2:
    ;newint.exe in 2
    
    push bx
    push es
    push ax
    push cx
    push dx

    mov bx,seg second_installed
    mov es,bx
    mov bx,offset second_installed   ;es:bx -> second_installed
    
    mov ah,3    ;write
    mov al,1    ;amount
    mov ch,0
    mov cl,2    ;number:2
    mov dx,0
    int 13h

    pop dx
    pop cx
    pop ax
    pop es
    pop bx
    ret
;-------------------------------------------------------------------------------
installer3:
    ;mainsub.exe in 3,4,5,6
    
    push bx
    push es
    push ax
    push cx
    push dx

    mov bx,seg third_installed
    mov es,bx
    mov bx,offset third_installed   ;es:bx -> third_installed
    
    mov ah,3    ;write
    mov al,4    ;amount
    mov ch,0
    mov cl,3    ;number:3
    mov dx,0
    int 13h

    pop dx
    pop cx
    pop ax
    pop es
    pop bx
    ret
first_installed:;XXXXXXXXXHere is 1st to be installed.XXXXXXXXXXXXXXXXXXXXXXXXXX
;CS:IP=0:7c00h
;      0:7e00h

booter:
    cli

    mov bx,860h
    mov ss,bx
    mov sp,400h     ;SS:SP=860h:400h

    ;boot newint

    mov bx,0
    mov es,bx
    mov bx,200h     ;ES:BX=0:200h

    mov ah,2        ;read
    mov al,1        ;amount
    mov ch,0
    mov cl,2        ;number:2
    mov dx,0
    int 13h         ;newint is ready, 0:200h~0:210h are empty

    push es:[9*4]
    pop es:[200h]
    push es:[9*4+2]
    pop es:[202h]   ;store old int9's address

    mov word ptr es:[9*4],210h
    mov word ptr es:[9*4+2],0    ;newint's address is 0:210h

    mov word ptr es:[204h],0
    mov word ptr es:[206h],7e0h  ;(dword ptr 0:204h)=7e0h:0 i.e. 0:7e00h

    mov word ptr es:[208h],7c00h
    mov word ptr es:[20ah],0     ;(dword ptr 0:208h)=0:7c00h i.e. 7c0h:0

    mov word ptr es:[20ch],0
    mov word ptr es:[20eh],0ffffh     ;(dword ptr 0:20ch)=0ffffh:0

    mov bx,7e00h    ;ES:BX=0:7e00h
    mov ah,2        ;read
    mov al,4        ;amount
    mov ch,0
    mov cl,3        ;number:3
    mov dx,0
    int 13h

    jmp dword ptr cs:[204h]

    db 0
    dw 510 dup (0aa55h)
second_installed:;XXXXXXXXHere is 2nd to be installed.XXXXXXXXXXXXXXXXXXXXXXXXXX
newint:
    ;two functions:
    ;    Press f1  to change the time's string's color
    ;    Press esc to jump to mainsub, i.e. 7e0h:0
    
    db 10h dup (0)
    ;10h 'free' bytes, newint starts at 0:210h
    
    push ax
    push di
    push es
    push cx

    in al,60h
    
    pushf
    call dword ptr cs:[200h]

    cmp al,3bh
    je prs_f1

    cmp al,01h
    je prs_esc
    
    newint_end:
        pop cx
        pop es
        pop di
        pop ax
        iret

    prs_esc:
        cl_kb:
            mov ah,0
            int 16h
            mov ah,1
            int 16h
            pushf
            pop ax
            and ax,0000000001000000b
            cmp ax,0
            je cl_kb
        jmp dword ptr cs:[204h]

    prs_f1:
        mov di,(80*4+8)*2+1
        mov ax,0b800h
        mov es,ax               ;ES:DI=0b800h:(80*4+8)*2+1
        
        mov al,es:[di]
        inc al
        or al,00001000b         ;highlight

        mov cx,49
        change_time_color:
            mov es:[di],al
            add di,2
            loop change_time_color
        jmp newint_end
third_installed:;XXXXXXXXXHere is 3rd to be installed.XXXXXXXXXXXXXXXXXXXXXXXXXX
;CS:IP=7e0h:0
mainsub:
    cli
    
    mov bx,860h
    mov ss,bx
    mov sp,400h         ;SS:SP=860h:400h

    call set_ui
    jmp wait_choice
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxTWO SUBxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
set_ui:
    push bp
    mov bp,sp
    push ax
    push es
    push di
    push cx
    push si

    cli

    mov di,0b800h
    mov es,di
    mov di,0                ;ES:DI=0b800h:0
    
    mov cx,80*25
    clearall:
        mov word ptr es:[di],0000111000000000b   ;default highlight yellow char
        add di,2
        loop clearall
        
    jmp show_options

    options:
        db '1) reset pc',               0;12
        db '2) start system',           0;16
        db '3) clock',                  0;09
        db '4) set clock',              0;13
        db '5) LOVE from Miss.Jia Ran',0;26

    show_options:
    ;(1)
    mov si,offset options - offset mainsub
    push si
    mov ah,10
    mov al,50
    mov cl,00001010b
    call show_str

    ;(2)
    mov si,offset options - offset mainsub + 12
    push si
    mov ah,11
    mov al,50
    mov cl,00001010b
    call show_str

    ;(3)
    mov si,offset options - offset mainsub + 12 + 16
    push si
    mov ah,12
    mov al,50
    mov cl,00001010b
    call show_str

    ;(4)
    mov si,offset options - offset mainsub + 12 + 16 + 9
    push si
    mov ah,13
    mov al,50
    mov cl,00001010b
    call show_str

    ;(5)
    mov si,offset options - offset mainsub + 12 + 16 + 9 + 13
    push si
    mov ah,15
    mov al,50
    mov cl,00001010b
    call show_str

    pop si
    pop cx
    pop di
    pop es
    pop ax
    pop bp
    ret
;===============================================================================
wait_choice:
    sti
    mov ah,0
    int 16h

    cmp al,'1'
    je option1
    cmp al,'2'
    je option2
    cmp al,'3'
    je option3
    cmp al,'4'
    je option4
    cmp al,'5'
    je option5
    jmp next_option

    option1:
        call f1
        jmp next_option
    option2:
        call f2
        jmp next_option
    option3:
        call f3
        jmp next_option
    option4:
        call f4
        jmp next_option
    option5:
        call f5
        jmp next_option

    next_option:
        jmp wait_choice
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxFIVE FUNCxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
f1:
    cli

    mov bx,0
    mov es,bx
    mov bx,20ch

    jmp dword ptr es:[bx]
;===============================================================================
f2:
    cli

    mov bx,0
    mov es,bx
    mov bx,7c00h

    mov ah,2
    mov al,1
    mov ch,0
    mov cl,1
    mov dh,0
    mov dl,80h
    int 13h

    mov bx,0
    mov es,bx
    mov bx,208h

    jmp dword ptr es:[bx]
;===============================================================================
f3:
    push bp
    mov bp,sp
    push ax
    push ds
    push si
    push cx

    sti

    jmp read_cmos
    itime:
        db '20yy mm-dd hh:mm:ss (Press F1 to change color :-)',0
        ;   012345678901234567890123456789012345678901234567890
        ;   0         1         2         3         4         5

    read_cmos:
        push cs
        pop ds
        mov si,offset itime - offset mainsub

        ;year
        mov al,9
        out 70h,al
        in al,71h
        mov ah,al
        and ax,0000111111110000b
        mov cl,4
        shr al,cl
        add ax,3030h
        mov word ptr ds:[si+2],ax

        ;month
        mov al,8
        out 70h,al
        in al,71h
        mov ah,al
        and ax,0000111111110000b
        mov cl,4
        shr al,cl
        add ax,3030h
        mov word ptr ds:[si+5],ax

        ;day
        mov al,7
        out 70h,al
        in al,71h
        mov ah,al
        and ax,0000111111110000b
        mov cl,4
        shr al,cl
        add ax,3030h
        mov word ptr ds:[si+8],ax

        ;hour
        mov al,4
        out 70h,al
        in al,71h
        mov ah,al
        and ax,0000111111110000b
        mov cl,4
        shr al,cl
        add ax,3030h
        mov word ptr ds:[si+11],ax

        ;minute
        mov al,2
        out 70h,al
        in al,71h
        mov ah,al
        and ax,0000111111110000b
        mov cl,4
        shr al,cl
        add ax,3030h
        mov word ptr ds:[si+14],ax

        ;second
        mov al,0
        out 70h,al
        in al,71h
        mov ah,al
        and ax,0000111111110000b
        mov cl,4
        shr al,cl
        add ax,3030h
        mov word ptr ds:[si+17],ax

        jmp show_itime

    show_itime:
        push si
        mov ax,0408h
        mov di,0b800h
        mov es,di
        mov di,4*80*2+8*2+1
        mov cl,es:[di]
        call show_str
        jmp read_cmos
;===============================================================================
f4:
    push cs
    pop ds
    mov bx,offset fake_time - offset mainsub - 1
    ;ds:bx -> fake_time-1

    mov di,0
    sti

    jmp f4_start
    fake_time:
        db 'y','y','m','m','d','d','h','h','m','m','s','s',0
        db  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 0
        ;   0   1   2   3   4   5   6   7   8   9  10  11 12
    f4_start:
        mov ax,0b800h
        mov es,ax
        mov cl,es:[80*2*4+2*8+1]
        mov ax,0408h
        inc bx
        push bx
        dec bx
        call show_str

    f4_wait:
        mov ah,0
        int 16h

        cmp ah,0eh
        je prs_bs
        cmp ah,1ch
        je prs_entr
        cmp al,'0'
        jb f4_wait
        cmp al,'9'
        ja f4_wait
        jmp prs_num

    prs_num:
        cmp di,12
        je f4_wait

        inc di
        mov ds:[bx+di+13],al

        mov ax,0b800h
        mov es,ax
        mov cl,es:[4*80*2+2*8+1]

        inc bx
        push bx
        dec bx
        mov ax,0408h
        call show_str

        add bx,14
        push bx
        sub bx,14
        mov ax,0408h
        call show_str

        jmp f4_wait

    prs_bs:
        cmp di,0
        je f4_wait

        mov byte ptr ds:[bx+di+13],0
        dec di

        mov ax,0b800h
        mov es,ax
        mov cl,es:[4*80*2+2*8+1]

        inc bx
        push bx
        dec bx
        mov ax,0408h
        call show_str

        add bx,14
        push bx
        sub bx,14
        mov ax,0408h
        call show_str

        jmp f4_wait

    prs_entr:
        ;y1)
        cmp di,0
        je f4_end_trans_y
        dec di

        mov al,9
        out 70h,al
        in al,71h
        and al,00001111b

        mov ch,ds:[bx+14]
        sub ch,30h
        mov cl,4
        shl ch,cl
        or al,ch

        mov ah,al
        mov al,9
        out 70h,al
        mov al,ah
        out 71h,al

        ;y2)
        cmp di,0
        je f4_end_trans_y
        dec di

        mov al,9
        out 70h,al
        in al,71h
        and al,11110000b

        mov ch,ds:[bx+15]
        sub ch,30h
        or al,ch

        mov ah,al
        mov al,9
        out 70h,al
        mov al,ah
        out 71h,al

        jmp prs_entr_cnt_mon

    f4_end_trans_y:
        jmp f4_end

    prs_entr_cnt_mon:
        ;m1)
        cmp di,0
        je f4_end_trans_mon
        dec di

        mov al,8
        out 70h,al
        in al,71h
        and al,00001111b

        mov ch,ds:[bx+16]
        sub ch,30h
        mov cl,4
        shl ch,cl
        or al,ch

        mov ah,al
        mov al,8
        out 70h,al
        mov al,ah
        out 71h,al

        ;m2)
        cmp di,0
        je f4_end_trans_mon
        dec di

        mov al,8
        out 70h,al
        in al,71h
        and al,11110000b

        mov ch,ds:[bx+17]
        sub ch,30h
        or al,ch

        mov ah,al
        mov al,8
        out 70h,al
        mov al,ah
        out 71h,al

        jmp prs_entr_cnt_d

    f4_end_trans_mon:
        jmp f4_end

    prs_entr_cnt_d:
        ;d1)
        cmp di,0
        je f4_end_trans_d
        dec di

        mov al,7
        out 70h,al
        in al,71h
        and al,00001111b

        mov ch,ds:[bx+18]
        sub ch,30h
        mov cl,4
        shl ch,cl
        or al,ch

        mov ah,al
        mov al,7
        out 70h,al
        mov al,ah
        out 71h,al

        ;d2)
        cmp di,0
        je f4_end_trans_d
        dec di

        mov al,7
        out 70h,al
        in al,71h
        and al,11110000b

        mov ch,ds:[bx+19]
        sub ch,30h
        or al,ch

        mov ah,al
        mov al,7
        out 70h,al
        mov al,ah
        out 71h,al

        jmp prs_entr_cnt_h

    f4_end_trans_d:
        jmp f4_end

    prs_entr_cnt_h:
        ;h1)
        cmp di,0
        je f4_end_trans_h
        dec di

        mov al,4
        out 70h,al
        in al,71h
        and al,00001111b

        mov ch,ds:[bx+20]
        sub ch,30h
        mov cl,4
        shl ch,cl
        or al,ch

        mov ah,al
        mov al,4
        out 70h,al
        mov al,ah
        out 71h,al

        ;h2)
        cmp di,0
        je f4_end_trans_h
        dec di

        mov al,4
        out 70h,al
        in al,71h
        and al,11110000b

        mov ch,ds:[bx+21]
        sub ch,30h
        or al,ch

        mov ah,al
        mov al,4
        out 70h,al
        mov al,ah
        out 71h,al

        jmp prs_entr_cnt_min

    f4_end_trans_h:
        jmp f4_end

    prs_entr_cnt_min:
        ;m1)
        cmp di,0
        je f4_end_trans_min
        dec di

        mov al,2
        out 70h,al
        in al,71h
        and al,00001111b

        mov ch,ds:[bx+22]
        sub ch,30h
        mov cl,4
        shl ch,cl
        or al,ch

        mov ah,al
        mov al,2
        out 70h,al
        mov al,ah
        out 71h,al

        ;m2)
        cmp di,0
        je f4_end_trans_min
        dec di

        mov al,2
        out 70h,al
        in al,71h
        and al,11110000b

        mov ch,ds:[bx+23]
        sub ch,30h
        or al,ch

        mov ah,al
        mov al,2
        out 70h,al
        mov al,ah
        out 71h,al

        jmp prs_entr_cnt_s

    f4_end_trans_min:
        jmp f4_end

    prs_entr_cnt_s:
        ;s1)
        cmp di,0
        je f4_end
        dec di

        mov al,0
        out 70h,al
        in al,71h
        and al,00001111b

        mov ch,ds:[bx+24]
        sub ch,30h
        mov cl,4
        shl ch,cl
        or al,ch

        mov ah,al
        mov al,0
        out 70h,al
        mov al,ah
        out 71h,al

        ;s2)
        cmp di,0
        je f4_end
        dec di

        mov al,0
        out 70h,al
        in al,71h
        and al,11110000b

        mov ch,ds:[bx+25]
        sub ch,30h
        or al,ch

        mov ah,al
        mov al,0
        out 70h,al
        mov al,ah
        out 71h,al

    f4_end:
        mov cx,13
        cl_time:
            mov byte ptr ds:[bx+14],0
            inc bx
            loop cl_time
        mov bx,0
        mov ds,bx
        mov bx,204h
        jmp dword ptr ds:[bx]
;===============================================================================
f5:
    sti

    jmp f5_set
    f5_image:
        ;   0  1  2  3   4  5  6  7   8  9 10 11  12 13 14 15  16 17 18 19  32 21 22 23  24 25 26 27  28 29 30 31  32 33 34 35  36 37 38
        db 32,32,32,32, 32,32,32,32, 32,32,03,03, 03,03,03,03, 03,03,32,32, 32,32,32,32, 03,03,03,03, 03,03,03,03, 32,32,32,32, 32,32, 0
        db 32,32,32,32, 32,32,32,32, 03,03,32,32, 32,32,32,32, 32,32,03,03, 32,32,03,03, 32,32,32,32, 32,32,32,32, 03,03,32,32, 32,32, 0
        db 32,32,32,32, 32,32,03,03, 32,32,32,32, 32,32,32,32, 32,32,32,32, 03,03,32,32, 32,32,32,32, 32,32,32,32, 32,32,03,03, 32,32, 0
        db 32,32,32,32, 03,03,32,32, 32,32,32,32, 32,32,32,32, 32,32,32,32, 32,32,32,32, 32,32,32,32, 32,32,32,32, 32,32,32,32, 03,03, 0
        db 32,32,32,32, 03,03,32,32, 32,32,32,32, 32,32,32,32, 32,32,32,32, 32,32,32,32, 32,32,32,32, 32,32,32,32, 32,32,32,32, 03,03, 0

        db 32,32,32,32, 03,03,32,32, 32,32,32,32, 32,32,32,32, 32,32,32,32, 32,32,32,32, 32,32,32,32, 32,32,32,32, 32,32,32,32, 03,03, 0
        db 32,32,32,32, 03,03,32,32, 32,32,32,32, 32,32,32,32, 32,32,32,32, 32,32,32,32, 32,32,32,32, 32,32,32,32, 32,32,32,32, 03,03, 0
        db 32,32,32,32, 03,03,03,03, 32,32,32,32, 32,32,32,32, 32,32,32,32, 32,32,32,32, 32,32,32,32, 32,32,32,32, 32,32,03,03, 03,03, 0
        db 32,32,32,32, 32,32,03,03, 32,32,32,32, 32,32,32,32, 32,32,32,32, 32,32,32,32, 32,32,32,32, 32,32,32,32, 32,32,03,03, 32,32, 0
        db 32,32,32,32, 32,32,32,32, 03,03,32,32, 32,32,32,32, 32,32,32,32, 32,32,32,32, 32,32,32,32, 32,32,32,32, 03,03,32,32, 32,32, 0

        db 32,32,32,32, 32,32,32,32, 32,32,03,03, 32,32,32,32, 32,32,32,32, 32,32,32,32, 32,32,32,32, 32,32,03,03, 32,32,32,32, 32,32, 0
        db 32,32,32,32, 32,32,32,32, 32,32,32,32, 03,03,32,32, 32,32,32,32, 32,32,32,32, 32,32,32,32, 03,03,32,32, 32,32,32,32, 32,32, 0
        db 32,32,32,32, 32,32,32,32, 32,32,32,32, 32,32,03,03, 03,03,32,32, 32,32,32,32, 03,03,03,03, 32,32,32,32, 32,32,32,32, 32,32, 0
        db 32,32,32,32, 32,32,32,32, 32,32,32,32, 32,32,32,32, 32,32,03,03, 32,32,03,03, 32,32,32,32, 32,32,32,32, 32,32,32,32, 32,32, 0
        db 32,32,32,32, 32,32,32,32, 32,32,32,32, 32,32,32,32, 32,32,32,32, 03,03,32,32, 32,32,32,32, 32,32,32,32, 32,32,32,32, 32,32, 0

    f5_set:
    mov si,offset f5_image - offset mainsub

    mov ah,6
    mov al,0

    mov cx,15
    f5_show_image:
        push si
        call show_str
        add si,39
        inc ah
        loop f5_show_image

    jmp f5_show_jxt
    jiaxintang:
        db 'Jia Xin Tang~',0
    f5_show_jxt:
        mov si,offset jiaxintang - offset mainsub
        push si
        mov ah,11
        mov al,15
        mov cl,00001100b
        call show_str

    wait_f5_esc:
        nop
        jmp wait_f5_esc
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxshow_strxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
show_str:
    ;ah=row, al=col, cl=color; push offset

    push bp
    mov bp,sp
    push ax
    push es
    push bx
    push cx
    push di
    push ds
    push si
    ;offset=[bp+4]

    mov bx,0b800h
    mov es,bx
    
    mov bx,ax        ;bh=row,bl=col
    mov ch,cl
    mov cl,8
    shr ax,cl        ;al=row
    mov ah,80*2
    mul ah           ;ax=row*80*2
    mov di,ax        ;di=row*80*2
    mov al,bl        ;al=col
    mov ah,2
    mul ah           ;ax=col*2
    
    add di,ax        ;ES:DI -> screen's ram

    push cs
    pop ds
    mov si,[bp+4]    ;DS:SI -> string's address

    show_char:
        mov cl,ds:[si]
        push cx
        mov ch,0
        jcxz show_char_end
        pop cx
        mov es:[di],cx
        inc si
        add di,2
        jmp show_char

    show_char_end:
        pop cx              ;pushed one cx but haven't poped when show_char ends
        
        pop si
        pop ds
        pop di
        pop cx
        pop bx
        pop es
        pop ax
        pop bp
        ret 2
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
code ends

end start

;=================LEGACY=================

经过多次试验, 有一个小小的发现: 如果在实模式下将时间设置成真实世界不存在的时间, e.g. 0月2日, 或者是9时77分. 首先因为 CMOS 采用 BCD 的形式存储时间, 这么设置是可行的. 但是, 设置完这种时间之后, 再引导 WindowsXP 的话, 能见到著名的 Windows logo 与等待条, 不过之后就是黑屏, 然后...就没有然后了.

这可能与 VirtualBox 的实现方式有关, 首先我猜测的前提是 VirtualBox 模拟出了一块主板. 这当然是必然的, 不然如何借助端口找到 CMOS? 注意, 我的意思是指...逻辑上的模拟, 好比模拟 CPU, 只需要算出几个寄存器的值, 我想 Windows 能知晓的极限也就是 CPU 中某些寄存器的值了, 骗过 Windows 的话, 这么做足够了.

然后, Windows 启动时, 其自身也会对 硬件环境 / 必要的环境 做一个检测, 就像 BIOS 那样. Windows 发现时间很奇怪, 所以无法启动也是合情合理的; 但是, 同样是在 CMOS 中时间异常的情况下, 如果选择 reset PC, BIOS 并没有在检测硬件时发现异常, 因为后续能够成功进入 DOG.exe,  而且显示的时间确实是错误时间. 不过这不重要, 这只是说明 BIOS 并不会对 CMOS 中的时间信息进行检查而已.

让我不解的是, 在时间设定正常的情况下, 比如物理世界的时间是2022年, 虚拟主板上 CMOS 的时间是2012年. 以下述为前提: 我将 VirtualBox 中的网络功能禁用, 将虚拟机内的网络提前断开. 按理说 start system 之后, Windows 显示的时间应该也是2012年, 但是...居然是2022年??

VirtualBox 模拟了主板这肯定假不了. 不过 XP 能显示正确的时间似乎又说明, XP 直接跑在我的 i7-11800H 上, 大概这次 VirtualBox 也没模拟主板什么的, 就是直接询问 Win11 当地时间然后转告给 XP.

出于各种考虑, 我猜想: VirtualBox 能识别实模式与保护模式, 并且提供不同的实现方案, 具体如上.

这个问题我浅尝辄止得了, 随便猜猜, 就这样吧. 不能思而不学, 毕竟才学了半年的计算机, 不懂也很正常吧?(首先 CMOS 允许这种诡异的时间存在得足够久就很不对劲, 衍生问题实在太多)


;====================跋===================

编写此课设, 需要对内存地址空间与端口地址空间有清晰的认识. 至少现在, 我并不会觉得C语言中的指针有多难了; 源程序中还有些许冗余之处, 有待改进, 刚好留到以后复习时练练手.

后续还有一个综合研究, 与C语言有关, 相当精彩. 有空再谈.

2.5个月之后更新: 笑死, 三个月没碰汇编语言, 相关知识已经全部忘记了捏~

  • 6
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
阅读下面的材料 : 开机后, CPU 自动进入到 FFF0:0 单元处执行,此处有一条跳转指令。 CPU 执行该指令后,转去执行 BIOS 中的硬件系统检测和初始化程序。 初始化程序将建立 BIOS 所支持的中断向量,即将 BIOS 提供的中断历程的入口地址登记在中断向量表中。 硬件系统检测和初始化完成后,调用 INT 19H 进行操作系统的引导。 如果设为从软盘启动操作系统,则 INT 19H 将主要完成一下工作: ( 1 )控制 0 号软驱,读取软盘 0 道 0 面 1 扇区的内容到 0 : 7C 00 。 ( 2 )将 CS:IP 指向 0 : 7C 00 。 软盘的 0 道 0 面 1 扇区中装有操作系统引导程序。 INT 19H 将其装到 0 : 7C 00 处后,设置 CPU 从 0 : 7C 00 开始执行此处的引导程序,操作系统被激活,控制计算机。 如果在 0 号软驱中没有软盘,或发生软盘 I/O 错误,则 INT 19H 将主要完成以下工作 ; (1) 读取硬盘 C 的 0 道 0 面 1 扇区的内容到 0 : 7C 00 ; (2) 将 CS:IP 指向 0 : 7C 00 。 这次课程设计的任务是编写一个可以自行启动计算机,不需要在现有操作系统环境中运行的程序。 改程序的功能如下: ( 1 )列出功能选项,让用户通过键盘进行选择,界面如下: 1 ) reset pc ; 重新启动计算机 2 ) Start system ; 引导现有的操作系统 3 ) Clock ; 进入时钟程序 4 ) Srt clock ; 设置时间 ( 2 )用户输入“ 1 ”后重新启动计算机。(提示:考虑 FFFF:0 ) ( 3 )用户输入“ 2 ” 后引导现有的操作系统。(提示:考虑硬盘 C 的 0 道 0 面 1 扇区) ( 4 )用户输入“ 3 ”后,执行动态现实当前日期,时间的程序。 现实格式如下:年 / 月 / 日 时:分:秒 进入此项功能后,一直动态现实当前的时间,在屏幕上将出现时间按秒变化的效果。(提示:循环读取 CMOS ) 当按下 F1 键后,改变现实颜色;按下 ESC 键后,返回到主选单。(提示:利用键盘中断) ( 5 )用户输入“ 4 ”后可更改当前的日期,时间,更改后返回到主选单。(提示:输入字符串) 下面给出的几点建议: ( 1 )在 DOS 下编写安装程序,在按转程序中包含任务程序; ( 2 )运行安装程序,将任务程序写到软盘上; ( 3 )若要任务程序可以在开机后自行执行,要将它写到软盘的 0 道 0 面 1 扇区上。如果程序长度大于 512B ,则需要用多个扇区存放,这种情况下,处于软盘 0 道 0 面 1 扇区中的程序就必须负责将其他扇区中的内容读入内存。 这个程序较为复杂,它用到了我们所学到的所有技术,需要进行仔细地分析和耐心地调试。这个程序对于我们的整个学习过程是具有总结性的,希望读者能够尽力完成。
一、程序功能: 1)重新启动计算机 2)引导现有操作系统 3)重启时进入时钟显示界面 4)修改CMOS时钟 二、运行步骤: 1)命令提示窗口输入“cmd”,将asm源文件放入当前目录下,将软驱放入软盘,运行masm、link,将代码写入软盘。 2)将电脑设置为从软驱启动,插入写入代码的软盘,重启电脑。此时会进入界面,界面显示为 1、reset pc 2、start system 3、clock 4、set clock 三、本程序涉及的一些问题 1、将启动代码写入软盘0面0道1扇区 2、读取\写入CMOS数据 3、重新启动计算机 4、引导现有操作系统 5、编写int 9键盘中断 6、带有一定格式的字符的动态显示\颜色改变\待修改项的闪烁效果 7、BCD码和ASCII码的转换 8、键盘缓冲区的情趣 9、对显存的直接操作 此外,寄存器的合理使用、编写中断程序时中断现场的保存与恢复及其在内存地址中的合理安排、数据在内存中的位置及其读取/写入、子程序在内存中地址的合理安排以防代码被覆盖、屏幕刷新、修改日期数据时对数据输入范围的判断、如何显示界面、与用户的互动等都是一些注意的细节。 四、注意: 1、运行后软盘0面0道1扇区会写入启动代码,如果直接在微软操作系统下读取,会出现“软盘尚未格式化”的提示,此时属正常情况,请勿格式化; 2、将电脑设置为优先从软驱启动; 3、选项4会真实修改系统时间,如果输入数据超出系统允许范围会导致进入不了现有操作系统,此时可进入安全模式下改回原来的系统时间。 五、感想 这个程序耗时两周,自己独立完成,收获良多,对汇编语言及计算机硬件有了更多的了解。编写代码期间出现很多问题,印象最深刻的是由于子程序的内存地址没有安排合理导致代码覆盖,思考良久才发现并解决。汇编语言在界面的显示及美化、与用户的有效互动、算法编写及可读性等方面与高级语言相比差距很大,当面对较多的变量时,如何有效使用有限的寄存器也是需要慎重考虑的问题。汇编语言除了效率高之外,可以直接对计算机硬件操作,这是高级语言无法相比的。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值