人造人 发表于 2020-2-27 17:49:41

课程设计2

assume cs:code, ds:data

stack segment
      db 64 dup(0)
stack ends

data segment
buf   db 1024 dup(0)
old_mbr db 512 dup(0)
data ends

code segment
start:
      mov   ax, data
      mov   ds, ax
      mov   es, ax
      mov   ax, stack
      mov   ss, ax
      mov   sp, 64
      
      ; 读取硬盘的逻辑扇区0到old_mbr
      mov   bx, offset old_mbr
      mov   dx, 0080h
      mov   cx, 0001h
      mov   ax, 0201h
      int   13h
      
      ; 把old_mbr写到硬盘的逻辑扇区2
      mov   bx, offset old_mbr
      mov   dx, 0080h
      mov   cx, 0003h
      mov   ax, 0301h
      int   13h
      
      ; 复制mbr段到buf
      push    ds
      mov   ax, mbr
      mov   ds, ax
      mov   si, offset mbr_start
      mov   di, offset buf
      mov   cx, mbr_end - mbr_start
      cld
      rep   movsb
      pop   ds
      
      ; 备份被分区表和引导标志占用的内容
      mov   si, offset buf
      mov   di, offset buf
      add   si, 1beh
      add   di, offset swap_data
      mov   cx, 66
      cld
      rep   movsb
      
      ; 复制分区表和引导标志
      mov   si, offset old_mbr
      mov   di, offset buf
      add   si, 1beh
      add   di, 1beh
      mov   cx, 66
      cld
      rep   movsb
      
      ; 把buf写到硬盘的逻辑扇区0和逻辑扇区1
      mov   bx, offset buf
      mov   dx, 0080h
      mov   cx, 0001h
      mov   ax, 0302h
      int   13h
      
      ; jmp   far ptr 0f000h:0fff0h
      db      0eah
      dw      0fff0h
      dw      0f000h
      
      mov   ax, 4c00h
      int   21h
code ends

mbr segment
mbr_start:
      mov   ax, cs
      mov   ds, ax
      mov   es, ax
      mov   ss, ax
      mov   sp, 7c00h
      
      mov   si, 7c00h
      mov   di, 0600h
      mov   cx, 256
      cld
      rep   movsw
      
      ; jmp   far ptr 60h:migrate
      db      0eah
      dw      migrate
      dw      60h
migrate:
      mov   ax, cs
      mov   ds, ax
      mov   es, ax
      
      sti             ; 确保允许中断
      
      ; 读取硬盘的逻辑扇区1到当前代码后面
      mov   bx, 200h
      mov   dx, 0080h
      mov   cx, 0002h
      mov   ax, 0201h
      int   13h
      
      ; 恢复被分区表和引导标志占用的内容
      mov   si, offset swap_data
      mov   di, 1beh
      mov   cx, 66
      cld
      rep   movsb
      
main_loop:
      call    cls
      call    disp_menu
      call    getchar
      cmp   al, '1'
      jne   @f
      call    reset_pc
      jmp   end_switch
@@:
      cmp   al, '2'
      jne   @f
      call    start_system
      jmp   end_switch
@@:
      cmp   al, '3'
      jne   @f
      call    clock
      jmp   end_switch
@@:
      cmp   al, '4'
      jne   @f
      call    set_clock
      jmp   end_switch
@@:
      cmp   al, '5'
      jne   @f
      call    uninstall_this
      jmp   end_switch
@@:
end_switch:
      jmp   main_loop
      
disp_menu:
      push    ax
      push    bx
      push    cx
      push    dx
      push    bp
      
      mov   bp, menu
      mov   dx, 0a20h
      mov   cx, 11
      mov   bx, 0007h
      mov   ax, 1300h
      int   10h
      
      mov   bp, menu + 11
      mov   dx, 0b20h
      mov   cx, 15
      mov   bx, 0007h
      mov   ax, 1300h
      int   10h
      
      mov   bp, menu + 26
      mov   dx, 0c20h
      mov   cx, 8
      mov   bx, 0007h
      mov   ax, 1300h
      int   10h
      
      mov   bp, menu + 34
      mov   dx, 0d20h
      mov   cx, 12
      mov   bx, 0007h
      mov   ax, 1300h
      int   10h
      
      mov   bp, menu + 46
      mov   dx, 0e20h
      mov   cx, 17
      mov   bx, 0007h
      mov   ax, 1300h
      int   10h
      
      ; 设置光标到下一行
      mov   ah, 02h
      mov   bh, 0
      mov   dx, 0f00h
      int   10h
      
      pop   bp
      pop   dx
      pop   cx
      pop   bx
      pop   ax
      ret
      
reset_pc:
      ; jmp   far ptr 0f000h:0fff0h
      db      0eah
      dw      0fff0h
      dw      0f000h
      ret
      
start_system:
      ; 读取硬盘的逻辑扇区2到0000h:7c00h
      xor   ax, ax
      mov   es, ax
      mov   bx, 7c00h
      mov   dx, 0080h
      mov   cx, 0003h
      mov   ax, 0201h
      int   13h
      
      mov   dl, 80h         ; 从硬盘启动
      
      ; jmp   far ptr 0000h:7c00h
      db      0eah
      dw      7c00h
      dw      0000h
      ret
      
clock:
      push    ax
      push    bx
      push    si
      
      mov   bx, offset color
      call    cls
      
clock_loop:
      call    read_time
      call    show_time
      mov   si, 19
      call    update_cursor
      call    kbhit
      cmp   ax, 0
      jz      clock_hlt
      call    getchar
      cmp   ah, 01h         ; Esc
      je      clock_exit
      cmp   ah, 3bh         ; F1
      jne   clock_hlt
      inc   byte ptr
clock_hlt:
      hlt
      jmp   clock_loop
      
clock_exit:
      mov   byte ptr , 07h
      pop   si
      pop   bx
      pop   ax
      ret
      
set_clock:
      push    ax
      push    bx
      push    si
      
      call    cls
      call    read_time
      call    show_time
      mov   bx, offset time
      xor   si, si
      call    update_cursor
      
set_clock_loop:
      call    getchar
      cmp   ah, 01h         ; Esc
      je      set_clock_exit
      cmp   ah, 1ch         ; Enter
      jne   @f
      call    write_time
      jmp   set_clock_exit
@@:
      cmp   ah, 4bh         ; 左箭头
      jne   @f
      cmp   si, 0
      je      set_clock_hlt
      dec   si
      call    update_cursor
      jmp   set_clock_hlt
@@:
      cmp   ah, 4dh         ; 右箭头
      jne   @f
      cmp   si, 18
      je      set_clock_hlt
      inc   si
      call    update_cursor
      jmp   set_clock_hlt
@@:
      cmp   al, '0'
      jb      set_clock_hlt
      cmp   al, '9'
      ja      set_clock_hlt
      mov   byte ptr , al
      call    show_time
set_clock_hlt:
      hlt
      jmp   set_clock_loop
      
set_clock_exit:
      pop   si
      pop   bx
      pop   ax
      ret
      
uninstall_this:
      xor   ax, ax
      mov   es, ax
      
      ; 读取硬盘的逻辑扇区2到0000h:7c00h
      mov   bx, 7c00h
      mov   dx, 0080h
      mov   cx, 0003h
      mov   ax, 0201h
      int   13h
      
      ; 把0000h:7c00h写到硬盘的逻辑扇区0
      mov   bx, 7c00h
      mov   dx, 0080h
      mov   cx, 0001h
      mov   ax, 0301h
      int   13h
      
      call    reset_pc
      ret
      
cls:
      push    ax
      push    cx
      push    di
      push    es
      mov   ax, 0b800h
      mov   es, ax
      mov   ax, 0720h
      xor   di, di
      mov   cx, 2000
      cld
      rep   stosw
      pop   es
      pop   di
      pop   cx
      pop   ax
      ret
      
getchar:
      mov   ah, 0
      int   16h
      ret
      
kbhit:
      mov   ah, 1
      int   16h
      jnz   @f
      xor   ax, ax
@@:
      ret
      
read_time:
      push    ax
      push    bx
      push    cx
      
      mov   bx, offset time
      mov   cx, 4
      
      ; 读取秒
      mov   al, 0
      out   70h, al
      in      al, 71h
      mov   ah, al
      and   al, 0fh
      shr   ah, cl
      add   al, '0'
      add   ah, '0'
      mov   , al
      mov   , ah
      
      ; 读取分
      mov   al, 2
      out   70h, al
      in      al, 71h
      mov   ah, al
      and   al, 0fh
      shr   ah, cl
      add   al, '0'
      add   ah, '0'
      mov   , al
      mov   , ah
      
      ; 读取时
      mov   al, 4
      out   70h, al
      in      al, 71h
      mov   ah, al
      and   al, 0fh
      shr   ah, cl
      add   al, '0'
      add   ah, '0'
      mov   , al
      mov   , ah
      
      ; 读取日
      mov   al, 7
      out   70h, al
      in      al, 71h
      mov   ah, al
      and   al, 0fh
      shr   ah, cl
      add   al, '0'
      add   ah, '0'
      mov   , al
      mov   , ah
      
      ; 读取月
      mov   al, 8
      out   70h, al
      in      al, 71h
      mov   ah, al
      and   al, 0fh
      shr   ah, cl
      add   al, '0'
      add   ah, '0'
      mov   , al
      mov   , ah
      
      ; 读取年
      mov   al, 9
      out   70h, al
      in      al, 71h
      mov   ah, al
      and   al, 0fh
      shr   ah, cl
      add   al, '0'
      add   ah, '0'
      mov   , al
      mov   , ah
      
      ; 读取世纪
      mov   al, 32h
      out   70h, al
      in      al, 71h
      mov   ah, al
      and   al, 0fh
      shr   ah, cl
      add   al, '0'
      add   ah, '0'
      mov   , al
      mov   , ah
      
      pop   cx
      pop   bx
      pop   ax
      ret
      
write_time:
      push    ax
      push    bx
      push    cx
      
      mov   bx, offset time
      mov   cx, 4
      
      ; 写入秒
      mov   al, 0
      out   70h, al
      mov   al,
      mov   ah,
      sub   al, '0'
      sub   ah, '0'
      shl   ah, cl
      or      al, ah
      out   71h, al
      
      ; 写入分
      mov   al, 2
      out   70h, al
      mov   al,
      mov   ah,
      sub   al, '0'
      sub   ah, '0'
      shl   ah, cl
      or      al, ah
      out   71h, al
      
      ; 写入时
      mov   al, 4
      out   70h, al
      mov   al,
      mov   ah,
      sub   al, '0'
      sub   ah, '0'
      shl   ah, cl
      or      al, ah
      out   71h, al
      
      ; 写入日
      mov   al, 7
      out   70h, al
      mov   al,
      mov   ah,
      sub   al, '0'
      sub   ah, '0'
      shl   ah, cl
      or      al, ah
      out   71h, al
      
      ; 写入月
      mov   al, 8
      out   70h, al
      mov   al,
      mov   ah,
      sub   al, '0'
      sub   ah, '0'
      shl   ah, cl
      or      al, ah
      out   71h, al
      
      ; 写入年
      mov   al, 9
      out   70h, al
      mov   al,
      mov   ah,
      sub   al, '0'
      sub   ah, '0'
      shl   ah, cl
      or      al, ah
      out   71h, al
      
      ; 写入世纪
      mov   al, 32h
      out   70h, al
      mov   al,
      mov   ah,
      sub   al, '0'
      sub   ah, '0'
      shl   ah, cl
      or      al, ah
      out   71h, al
      
      pop   cx
      pop   bx
      pop   ax
      ret
      
show_time:
      push    ax
      push    bx
      push    cx
      push    dx
      push    bp
      
      mov   bp, offset time
      mov   dx, 0c1fh
      mov   cx, 19
      mov   bx, offset color
      mov   bx,
      mov   ax, 1300h
      int   10h
      
      pop   bp
      pop   dx
      pop   cx
      pop   bx
      pop   ax
      ret
      
update_cursor:
      push    ax
      push    bx
      push    dx
      mov   ah, 02h
      mov   bh, 0
      mov   dx, 0c1fh
      add   dx, si
      int   10h
      pop   dx
      pop   bx
      pop   ax
      ret
      
menu:
      db '1) reset pc'
      db '2) start system'
      db '3) clock'
      db '4) set clock'
      db '5) uninstall this'
      
time    db '0000/00/00 00:00:00'
color   dw 0007h
      
; 这里存放被分区表和引导标志占用的内容
swap_data:
      db 66 dup(0)
mbr_end:
mbr ends
end start

理想小青年 发表于 2020-3-4 10:21:22

{:10_256:}

人造人 发表于 2020-3-4 12:03:04

理想小青年 发表于 2020-3-4 10:21


好久不见
^_^

jzzc 发表于 2020-3-6 14:50:13

{:10_254:}大大还会汇编啊

人造人 发表于 2020-3-6 14:58:02

jzzc 发表于 2020-3-6 14:50
大大还会汇编啊

我主修C/C++,学过汇编语言,略懂python和java
C/C++排第一,汇编语言是第二,python略比java强
^_^

jzzc 发表于 2020-3-6 15:07:49

人造人 发表于 2020-3-6 14:58
我主修C/C++,学过汇编语言,略懂python和java
C/C++排第一,汇编语言是第二,python略比java强
^_^

哈哈哈,您是我奋斗的目标{:10_279:}

人造人 发表于 2020-3-6 15:12:37

jzzc 发表于 2020-3-6 15:07
哈哈哈,您是我奋斗的目标

加油
^_^

理想小青年 发表于 2020-3-6 22:24:16

人造人 发表于 2020-3-4 12:03
好久不见
^_^

一直在忙工作小男神{:9_231:}

YQ8888 发表于 2020-9-14 10:41:21

几百行代码瞬间下来了,666

sbx 发表于 2020-9-24 16:49:06

我来学习的!
页: [1]
查看完整版本: 课程设计2