操作系统入门(六) - 2 - 加入中断在保护模式试试看

超详细汇编注释 操作系统实验二 操作系统的引导(哈工大李治军) 实验二 操作系统的引导 哈工大李治军 超级详细的汇编代码,一字一句带你解读源码 实验前必看 阅读详情
加入中断试试看
2006-5-20 blog.youkuaiyun.com/flyback fly-back@163.com
一直都没有考虑中断 , 现在在保护模式下把中断加上去看看是怎么回事
现在的文件有 :
文件KERNEL.asm
; ==================================
;;  文件 :    KERNEL.asm
;;  作用 :    系统在进入保护模式之前
;;          要进行的初始化操作包括 :
 
;       1. 载入 32 位系统文件 system.img
;       2. 设置 GDT 和中断 ( 空的 ) 在 32 位的时候再设置
 
 
;;  创建日期 :2006/04/30 flyback
;;  修改日期 :2006/05/07 flyback
;;    http://blog.youkuaiyun.com/flyback
;;    fly-back@163.com
; ==================================
 
global start
extern _pntchr
extern _cls
extern _NextLine
extern _readsystem
[section .text]
[bits 16]
start: 
 
    mov ax, cs
    mov ds, ax
    mov ss, ax
    mov sp, 0xfff0
    sti
    call _cls
   
    lea si, [dword KernelLoad]
    call _pntchr
    call _NextLine
 
    lea si, [dword welcomemsg]
    call _pntchr
    call _NextLine
 
    call _readsystem
 
    ; 打开 A20
    in al, 92h
    or al, 00000010b
    out 92h, al
    ; end 打开 A20
    ; 设置 GDT
    cli
    lea si, [dword gdtr]
    lgdt [si]
    ; end 设置 GDT
    ; 设置 idt
    lea si, [dword idtr]
    lidt [si]
    ; end 设置 idt
 
    mov eax, cr0
    or eax,1
    mov cr0, eax
   
    jmp dword codesel:SYSSEG * 0x10 + SYSOFF
[bits 32]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;   设置中断 0
;   显示 20 在屏幕上
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
int0x0:
    pusha  
    mov ax,datasel
    mov gs,ax
    mov byte[gs:dword 0xB8000],'2'
    mov byte [gs:dword 0xB8002],'0'
    popa
    iret
 
int0x1:
; =======
;   清屏幕
; =======
    pusha
    mov ax, datasel
    mov ds, ax
    mov es, ax
    mov eax, dword 0xb8000
    mov edi, eax
    mov ecx, 25 * 80
    mov ah, 0x7
    mov al, ' '
    rep stosw
    popa
    iret
[bits 16]
gdtr :
dw gdtend - gdt - 1                         ; gdt 的长度
dd gdt                                  ; gdt 的物理地址
gdt:
    gdt0:
    dw 0,0,0,0                             ; 据说是一定要为 0 否则会有错
codesel_gdt:
    dw    0xffff                         ; 界限 Limit 值 = 0x100000 * 0x1000 = 4GB
    dw 0                               ; 基地址 = 0
    dw     0x9A00                         ; 表示代码段 可读可执行
    dw    0x00CF                         ; 粒度(不知道是什么意思)
datasel_gdt:
    dw    0xffff                         ; 4GB
    dw 0x0                             ; 基地址
    dw     0x9200                         ; 数据段 可读可写
    dw     0x00CF                         ; 粒度
gdtend:
 
codesel equ codesel_gdt - gdt
datasel equ datasel_gdt - gdt
 
align 4
idtr:   dw idt_end - idt - 1   ; IDT limit
    dd idt         ; linear, physical address of IDT
   
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;   interrupt descriptor table (IDT)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
idt:
    dw int0x0 - $$            ; 这里是 offset
    dw codesel
    db 0
    db 0x8E
    dw SYSSEG / 0x1000    ; 这里为 0x9000 / 0x1000 = 0x9 如果程序用到 int 0x0 的时候则跳转到 8:0x9:int0x0
 
    dw int0x1 - $$
    dw codesel
    db 0
    db 0x8E
    dw SYSSEG / 0x1000
idt_end:   
   
segment .data
 
welcomemsg    db 'Welcome to DIY OS!'
CopyRight    db ' Create by http://blog.youkuaiyun.com/flyback.',0
KernelLoad    db 'KERNEL.img was loaded!',0
 
SYSSEG     equ 0x9000
SYSOFF     equ 0x1000
 
 
文件fatboot.asm
;;  文件 :fatboot.asm
;;  作用 :    从 7c00h 处启动
;;          把 kernel.img 载入到 0x90000 的地方
;;          用 32 位方式执行  
;;  有文件系统 ,1.44M 512bits/80sec 软盘启动,
;;  创建日期 :2004/01/30 flyback
;;  修改日期 :2006/04/24 flyback
;;    http://blog.youkuaiyun.com/flyback
;;    mailto:fly-back@163.com
;;      ===================================
 
 
    %define loadpoint 0x9000              ; 载入点,初始化程序载入到 9000h 的地方
    %define loadoffset 0x0               
 
    bits 16
    ORG 0x7c00    ; 启动入口地址
main:
    jmp short start       ; 跳转到开始程序入口
    nop         ;
 
; 引导区文件系统数据
;----------------------------------------------------------------------------
    brOEM       DB ' -My-0S.'        ; 0003h - 引导程序的名字
    brBPS       DW 0x200        ; 000Bh - 每扇区的字节数 512
    brSPC       DB 0x01            ; 000Dh - 每簇扇区数
    brResCount   DW    0x0001     ; 000Eh - 保留扇区数
    brFATs     DB 0x02            ; 0010h - FAT 备份数
    brRootEntries    DW    0x00e0     ; 0011h - 根目录入口数
    brSectorCount   
                DW 2880        ; 0013h - 磁盘容量扇区数 < 32MB
    brMedia     DB 240         ; 0015h - 媒体描述符
    brSPF       DW 9           ; 0016h - 每 FAT 扇区数
    brSPH       DW 18         ; 0018h - 每磁道扇区数
    brHPC       DW 2           ; 001Ah - 盘面数
    brHidden        DD 0            ; 001Ch - 隐藏扇区数
    brSectors    DD 0           ; 0020h - 如果大于 32m 的扇区总数
                DB 0           ; 0024h - 物理驱动器号
                DB 0           ; 0025h - 系统保留
                DB 29H         ; 0026h - 扩展扇区标记(包含 29h )
    brSerialNum     DD    00000006H    ; 0027h - 卷 ID
    brLabel     DB    'teachosdisk'    ; 002Bh - 卷标
    brFSID     DB    'FAT12   '        ; 0036h - 系统保留
;------------------------------------------------------------------------
 
start:
    cli         ; 关中断,防止意外中断打断程序执行
    mov ax, cs    ;
    mov ds, ax    ; 设置数据段
    mov es, ax    ;
 
    mov ax, 0x0000; 设置堆栈段
    mov ss, ax
    mov sp, 0ffffh ; 堆栈入口
 
    sti         ; 开中断
       
    mov si, loadmsg ; 调用显示载入信息
    call pntchr
 
    ; 把磁盘目录信息载入到 7c00:0200 的地方
loadroot:
    mov     cx, 0
    mov     dx, 0  
    mov     ax, 0x0020            ; 32 个字节 / 文件
    mul     WORD [brRootEntries] ; 32*224 (文件数) = 7168 (最多所有文件所占的字节数)
    div     WORD [brBPS]         ; 7168/512 = 14 (Root dir) 文件的目录描述字节占用的扇区数 14
    xchg        ax, cx             ; CX = 14
    mov     al, [brFATs]            ; 2
    mul     word [brSPF]         ; 9 * 2 = 18
    add     ax, word [brResCount]    ; 18 + 1 now AX = 19
    mov     WORD[datasector], ax     ; 目录起始的扇区 19
    add     WORD[datasector], cx     ; 数据区起始扇区 33
 
    ; 目录放入 0x0200 内存
    mov bx, 0x0200
    call ReadSec
 
    ; 比较目录中是否有 init.img 文件存在
   mov     cx, WORD [brRootEntries] ; CX:224 在目录的所有文件中寻找
   mov     di, 0x0200          ; 从目录入口处开始 0x200
.LOOP:
    push    cx                        ; 保护 CX = 224
   
    mov     cx, kernellen           ; 8 个文件名称和 3 个扩展名称
    lea     si, [kernelname]            ;
    push        di                 
    repe    cmpsb                   ; stop compare if cx >0 or the
                                ; first unequal is met(zf=1)!
    pop     di
    je    loadfiledec             ;if zf = 1, jmp LOAD_FAT!(Seek OK!)
    pop     cx
   add     di, 0x0020              ; 跳到下一个目录入口
    loop    .LOOP                 ; cx 自动减
    jmp     failure
 
    ; 载入文件描述子节
loadfiledec:
    ; 把启动的镜像文件 *.img 文件的起始单元保存起来
    mov   si, CRLF
    call    pntchr
    mov si, loadfat
    call    pntchr 
    lea si, [kernelname]
    call    pntchr
 
   mov     dx, WORD [di + 0x001A]             ;the file's first cluster
    mov     WORD [cluster], dx                  ; store the first cluster
   
    ; 计算 fat 的大小并保存到 07c00:0x0200(ds:bx)
   xor     ax, ax
   mov     al, BYTE [brFATs]                ; al:2
    mul     WORD [brSPF]                ; AH:18 = 9*2
   mov     cx, ax                              ; CX:18
 
    ; 读取数据放入到 0x7c00:0x0200 ds:bx
   mov     ax, WORD [brResCount]          ; AX:1
   mov     bx, 0x0200                          ;
    call    ReadSec                         ; AX:1 CX:18 BX:0200
 
    ; 读取 img 放入 9000:0x0000 处
    mov ax, loadpoint
    mov es, ax
    mov bx, loadoffset 
    push    bx
 
LOAD_IMAGE:
   mov     ax, WORD [cluster]    ; cluster to read
    pop     bx                    ; buffer to read into
    call    ClusterLBA         ; convert cluster to LBA
                            ; AX:[cluster] ES:BX[9000:0000](dest)
   xor     cx, cx
   mov     cl, BYTE [brSPC]        ; CL:1
    call    ReadSec             ; AX:LBA CX:1 BX:0000 ES:0100
    push    bx
   
    ; 计算下一个单元
   mov     ax, WORD [cluster]    ; identify current cluster
   mov     cx, ax              ; copy current cluster
   mov     dx, ax              ; copy current cluster
   shr     dx, 0x0001          ; divide by two
 
   add     cx, dx              ; sum for (3/2)
   mov     bx, 0x200       ; location of FAT in memory
   add     bx, cx                            ; index into FAT
   mov     dx, WORD [bx]             ; read two bytes from FAT
   test    ax, 0x0001
    jnz     .ODD_CLUSTER
 
.EVEN_CLUSTER:
   and     dx, 0000111111111111b               ; take low twelve bits
    jmp     .DONE
 
.ODD_CLUSTER:
   shr     dx, 0x0004                          ; take high twelve bits
 
.DONE:
    mov     WORD [cluster], dx                  ; store new cluster
   cmp     dx, 0x0FF0                          ; test for end of file,>=0x0FF0: end or bad!
    jb      LOAD_IMAGE                         ; if dx<0x0ff0 (CF=1), jmp Load_image
    DONE:                                        ; this Label is not used!
    jmp gotopm
   
failure:
    mov si, CRLF
    call pntchr
    mov si, loadfail
    call pntchr
    hlt
   
; ---------------- 子程序区 -------------------------
 
;********************* 显示字符串 ********************************************
;
;
;
;***************************************************************************
 
pntchr:
    pusha
.pnt:
    lodsb               ; 从 DS:SI 装载一个字符到 AL
    or al,al                ;
    jz endpntchr           ; 如果 al = 0, 返回
                        ;
    mov ah,0x0E         ;
    mov bx,0x004a       ; 
    int 0x10                ; 调用 bios 中断显示字符
    jmp .pnt            ;
                        ;
endpntchr:             ;
    popa
    ret                 ; 返回
 
 
;*************************************************************************
; PROCEDURE ReadSec
; 从 ax+1 的地方把 cx 个扇区载入到 es:bx 的内存
; 注意扇区是从 2 开始, 1 扇区已经读入了
;*************************************************************************
ReadSec:
.Main:
 
.secloop:
    push    ax
    push    bx
    push    cx                                    ;protect ax, bx, cx
 
    call    LBACHS          ; 调用转换
 
   mov     ah, 0x02        ; BIOS 读取扇区命令
   mov     al, 0x01        ; 一个扇区
   mov     ch, BYTE [Track]    ; track
   mov     cl, BYTE [Sector]    ; sector
   mov     dh, BYTE [Head] ; head
   mov     dl, 0           ; 因为是 a: 所以为 0
    int     0x13            ; 调用中断
 
    jnc     .SUCCESS                            ; test for read error
   
    xor ax, ax
 
    pop     cx
    pop     bx
    pop     ax
    jnz .secloop
    jmp    failure         ; 错误则显示出错信息并停止
    hlt
   
.SUCCESS
    mov    si, Progress
    call      pntchr
    pop     cx
    pop     bx
    pop     ax
 
    add bx, WORD [brBPS]    ; 读取下一个扇区的内容
    inc ax                
    loop    .Main           ; cx -= 1, if cx != 0, jmp .main
    ret
 
;*************************************************************************
; PROCEDURE LBACHS
; 转换逻辑块访问为读取磁盘所使用的磁道,盘面,扇区
; 相对扇区 = ( 逻辑扇区 / 每磁道扇区数 ) + 1
; 相对盘面    = ( 逻辑扇区 / 每磁道扇区数 ) MOD 盘面数
; 相对磁道  = 逻辑扇区 / ( 每磁道扇区数 * 盘面数 )
;*************************************************************************
LBACHS:
   xor     dx, dx              ; dx = 0
    div     WORD [brSPH]        ; div m16: ax/18 -> 商 :ax 余数 :dx
    inc     dl                    ;
    mov     BYTE [Sector], dl     ;sector No relative to the Track
   xor     dx, dx              ; dx = 0
    div     WORD [brHPC]        ; ax/2 -> 商 :ax 余数 :dx
    mov     BYTE [Head], dl      ;
    mov     BYTE [Track], al      ;
    ret
 
;*************************************************************************
; PROCEDURE ClusterLBA
; 转换单元访问到直接扇区访问
; LBA = (cluster - 2) * sectors per cluster
;*************************************************************************
ClusterLBA:
sub     ax, 0x0002                          ; zero base cluster number
xor     cx, cx
mov     cl, BYTE [brSPC]        ; convert byte to word
mul     cx
add     ax, WORD [datasector]               ; base data sector
ret
 
;-------------------- 数据区 -------------------------------
 
loadmsg     db 'Boot',0                    ; 要显示的字符窜以 0 结尾
loadfail        db 'Load Fail',0                 ; 载入失败信息
Sector     db 0x00
Head        db 0x00
Track       db 0x00
datasector    dw 0x0000                    ; 33 数据区起始扇区号
rootaccess    equ 0x0200                    ; 存放目录数据的偏移地址
cluster     dw 0x0000
CRLF            db 13,10,0
Progress        db ".", 0
loadfat     db 'Load', 0                   ; 字符串,回车,换行, 0
kernelname    db "KERNEL IMG"                ; 11 chars          
kernellen       equ $ - kernelname             ; 长度
 
gdtr :
dw gdtend - gdt - 1                         ; gdt 的长度
dd gdt                                  ; gdt 的物理地址
gdt:
    gdt0:
    dw 0,0,0,0                             ; 据说是一定要为 0 否则会有错
codesel_gdt:
    dw    0xffff                         ; 界限 Limit 值 = 0x100000 * 0x1000 = 4GB
    dw 0                               ; 基地址 = 0
    dw     0x9A00                         ; 表示代码段 可读可执行
    dw    0x00CF                         ; 粒度(不知道是什么意思)
datasel_gdt:
    dw    0xffff                         ; 4GB
    dw 0x0                             ; 基地址
    dw     0x9200                         ; 数据段 可读可写
    dw     0x00CF                         ; 粒度
gdtend:
 
codesel equ codesel_gdt - gdt
datasel equ datasel_gdt - gdt
 
;       从这里启动 KERNEL, 原来要作为保护模式的跳转
gotopm:
    jmp dword loadpoint:loadoffset
 
; -----------------------------------------------------------------
times 510 - ($ - $$) db 0         ; 保证 boot 区有 512 个字节
    dw 0AA55h                ; boot 区标记
 
times 1474560 - ( $ - $$) db 0       ; 大小为 1.44M
 
 
文件 pnt.asm
; ==================================
;;  文件 :    pnt.asm
;;  作用 :    需要调用的显示部分子程序
 
;;  创建日期 :2006/04/30 flyback
;;  修改日期 :2006/05/07 flyback
;;    http://blog.youkuaiyun.com/flyback
;;  fly-back@163.com
; ==================================
[bits 16]
[global _pntchr]
[global _cls]
[global _NextLine]
[global _Num2Str]
[global _ShowAddress]
[global _NextCursor]
segment .data
 
_row        dw 0
_col            dw 0
 
[section .text]
   
_pntchr:
    push ebx
    push eax
    push si
    push di
    push cx
    push es
 
    mov ax, 0xb800
    mov es, ax
 
    push si
    lea si, [dword _row]   
    mov ax, [si]
 
    mov bx, 80 * 2
    mul bx
 
    lea si, [dword _col]
    add ax, [si]
    mov di, ax
    pop si
 
.pnt:
    mov al, byte[ds:si]
    test al, 0xff
    jz .endpntchr
 
    mov byte[es:di], al
    inc di
    mov byte[es:di], 0x7
    inc di
    inc si
    call _NextCursor
    jmp .pnt                ;
.endpntchr:             ;
    pop es
    pop cx
    pop di
    pop si
    pop eax
    pop ebx
    ret                 ; 返回
 
; =======
;   清屏幕
; =======
_cls:
    push ax
    push es
    push di
    push ecx
    push si
    ; push fs
    mov ax, 0xb800
    mov es, ax
    mov ax, 0
    mov di, ax
    mov ecx, 25 * 80
    mov ah, 0x7
    mov al, ' '
    rep stosw
    mov ax, 0
    mov es, ax
    lea si, [dword _row]
    mov [si], ax
    lea si, [dword _col]
    mov [si], ax
 
    ; pop fs
    pop si
    pop ecx
    pop di
    pop es
    pop ax
    ret
; =============
;   跳到下一行
; =============
_NextLine:
    push si
    lea si, [dword _row]
    inc word[si]
    lea si, [dword _col]
    mov word [si], 0
    pop si
    ret
 
; =================
;   设置光标的下一个位置
; =================
_NextCursor:
    push si
    lea si, [dword _col]
    inc word[si]
    inc word[si]
    cmp word [si], 80 * 2
    jne .addcol
    mov word [si], 0
    lea si, [dword _row]
    inc word[si]
.addcol:
    pop si
    ret
 
; ===================
;   显示指定位置的地址内容
;   入口参数 :
;       si = 有效地址
;       cx = 内容个数
; ===================
_ShowAddress:
    push eax
.lod   
    lodsb
    or cx,cx
    jz .end
   
    push si
    call _Num2Str
    call _pntchr
    ; call _NextLine
    pop si
    loop .lod
.end
    pop eax
    ret
 
; ===========
;   把 al 的数按 16
;   进制显示出来
;   al = num
; ===========
_Num2Str:
   
    push bx
    push eax
 
    jmp .handle
    .show db ' '
    .dath db 0
    .datl db 0,0
    .tab db '0123456789ABCDEF'
.handle:
    and ax, 0xff
    push ax
    and ax, 0x0f
    lea si, [dword .tab]
    add si, ax
    mov al, byte[si]
 
    lea si, [dword .datl]
    mov [si], al
   
    pop ax
    shr ax, 4
    and ax, 0x0f
 
    lea si, [dword .tab]
    add si, ax
    mov al, byte[si]
    lea si, [dword .dath]
    mov [si], al
    lea si, [dword .show]
    pop eax
    pop bx
   
    ret
 
文件readdisk.asm
; ==================================
;;  文件 :    readdisk.asm
;;  作用 :    需要调用的读读磁盘文件子程序
 
;;  创建日期 :2006/04/30 flyback
;;  修改日期 :2006/05/07 flyback
;;    http://blog.youkuaiyun.com/flyback
;;  fly-back@163.com
; ==================================
[bits 16]
[extern _pntchr]
[extern _cls]
[extern _NextLine]
[extern _Num2Str]
[extern _ShowAddress]
[global _readsystem]
 
segment .data
align 4
progress           db '.', 0
Load                db ' Loading system file now, please wait', 0
ErrorMsg            db ' An error occur!',0
SystemFileName   db 'SYSTEM IMG'
SystemFileNameLen    equ $ - SystemFileName
protectmode     db ' Goto protected mode',0
LoadRootMsg     db ' Loading root',0
LoadFileDescriptor   db ' Loading file descriptor',0
LoadSystemImage db ' Loading system file image',0
NotFound            db ' File not found!', 0
 
bpsadd          equ 0xb     ;brBPS     DW 0x200        ; 000Bh - 每扇区的字节数 512
spcadd          equ 0xd     ;brSPC     DB 0x01            ; 000Dh - 每簇扇区数
rescountadd         equ 0xe     ;brResCount DW    0x0001     ; 000Eh - 保留扇区数
fatsadd         equ 0x10        ;brFATs     DB 0x02            ; 0010h - FAT 备份数
rootentriesadd   equ 0x11        ;brRootEntries   DW    0x00e0     ; 0011h - 根目录入口数
sectorscountadd equ 0x13        ;brSectorCount DW    2880        ; 0013h - 磁盘容量扇区数 < 32MB
mediaadd            equ 0x15        ;brMedia        DB    240         ; 0015h - 媒体描述符
spfadd          equ 0x16        ;brSPF     DW 9           ; 0016h - 每 FAT 扇区数
sphadd          equ 0x18        ;brSPH     DW 18         ; 0018h - 每磁道扇区数
hpcadd          equ 0x1a        ;brHPC     DW 2           ; 001Ah - 盘面数
hideadd         equ 0x1c        ;brHidden        DD 0            ; 001Ch - 隐藏扇区数
sectors         equ 0x20        ;brSectors   DD 0           ; 0020h - 如果大于 32m 的扇区总数
                            ;DB 0           ; 0024h - 物理驱动器号
                            ;DB 0           ; 0025h - 系统保留
                            ;DB 29H         ; 0026h - 扩展扇区标记(包含 29h )
                            ;brSerialNum     DD    00000006H    ; 0027h - 卷 ID
                            ;brLabel        DB    'teachosdisk'    ; 002Bh - 卷标
                            ;brFSID     DB    'FAT12   '        ; 0036h - 系统保留
 
SYSSEG     equ 0x9000
SYSOFF     equ 0x1000
 
Sector     db 0x00
Head        db 0x00
Track       db 0x00
datasector    dw 0x0000                    ; 33 数据区起始扇区号
cluster     dw 0x0000
 
segment .text
;*************************************************************************
; PROCEDURE ReadSec
; 从 ax+1 的地方把 cx 个扇区载入到 es:bx 的内存
; 注意扇区是从 2 开始, 1 扇区已经读入了
;*************************************************************************
ReadSec:
.Main:
 
.secloop:
    push        ax
    push        bx
    push        cx                                  ;protect ax, bx, cx
   
    call        LBACHS         ; 调用转换
 
    mov     ah, 0x02        ; BIOS 读取扇区命令
    mov     al, 0x01        ; 一个扇区
 
    lea     si, [dword Track] 
    mov     ch, [si]    ; track
 
    lea     si, [dword Sector]
    mov     cl, [si]    ; sector
 
    lea     si, [dword Head]
    mov     dh, [si]    ; head
 
    mov     dl, 0           ; 因为是 a: 所以为 0
    int     0x13            ; 调用中断
 
    jnc     .SUCCESS        ; test for read error
 
    xor     ax, ax
   
    pop     cx
    pop     bx
    pop     ax
   
    jnz     near    .secloop
 
    jmp     failure         ; 错误则显示出错信息并停止
   
.SUCCESS
    lea     si,[dword progress]
    call        _pntchr
 
    pop     cx
    pop     bx
    pop     ax
 
    add     bx, [fs:bpsadd] ; 读取下一个扇区的内容
 
    inc ax                
    loop    .gotomain            ; cx -= 1, if cx != 0, jmp .main
    ret
 
    ;    到 .Main 已经不能用普通跳转了
    ;   因为 loop 只能是 short jmp
 
.gotomain:
    jmp near .Main
 
;*************************************************************************
; PROCEDURE LBACHS
; 转换逻辑块访问为读取磁盘所使用的磁道,盘面,扇区
; 相对扇区 = ( 逻辑扇区 / 每磁道扇区数 ) + 1
; 相对盘面    = ( 逻辑扇区 / 每磁道扇区数 ) MOD 盘面数
; 相对磁道  = 逻辑扇区 / ( 每磁道扇区数 * 盘面数 )
;*************************************************************************
LBACHS:
    xor     dx, dx             ; dx = 0
    div     WORD [fs:sphadd]     ; div m16: ax/18 -> 商 :ax 余数 :dx
    inc     dl                  ;
    lea     si,[dword Sector]
    mov     [si], dl                ; sector No relative to the Track
 
    xor     dx, dx             ; dx = 0
    div     word [fs:hpcadd]     ; ax/2 -> 商 :ax 余数 :dx
 
    lea     si, [dword Head]
    mov     [si], dl        ;
 
    lea     si, [dword Track]
    mov     [si], al        ;
 
    ret
 
;*************************************************************************
; PROCEDURE ClusterLBA
; 转换单元访问到直接扇区访问
; LBA = (cluster - 2) * sectors per cluster
;*************************************************************************
ClusterLBA:
    sub     ax, 0x0002                          ; zero base cluster number
    xor     cx, cx
    mov     cl, BYTE [fs:spcadd]        ; convert byte to word
    mul     cx
 
    lea     si, [dword datasector]
    add     ax, [si]               ; base data sector
 
    ret
 
 
_readsystem:   
    lea     si, [dword Load]
    call        _pntchr
 
    mov     ax, 0x7c0
    mov     fs, ax 
    mov     es, ax
 
loadroot:
    call        _NextLine
    lea     si, [dword LoadRootMsg]
    call        _pntchr
 
    mov     cx, 0
    mov     dx, 0  
 
    mov     ax, 0x0020            ; 32 个字节 / 文件
 
    ; mul       WORD [brRootEntries] ; 32*224 (文件数) = 7168 (最多所有文件所占的字节数)
    mul     word [fs:rootentriesadd]
 
    ; div       WORD [brBPS]         ; 7168/512 = 14 (Root dir) 文件的目录描述字节占用的扇区数 14
    div     word [fs:bpsadd]
 
    xchg        ax, cx             ; CX = 14
 
    ; mov       al, [brFATs]            ; 2
    mov     al, [fs:fatsadd]
   
    ; mul       word [brSPF]         ; 9 * 2 = 18
    mul     word [fs:spfadd]
   
    ; add       ax, word [brResCount]    ; 18 + 1 now AX = 19
    add     ax, word [fs:rescountadd]
   
    ; mov       WORD[datasector], ax     ; 目录起始的扇区 19
    lea     si, [dword datasector]
    mov     [si], ax
   
    ; add       WORD[datasector], cx     ; 数据区起始扇区 33
    lea     si, [dword datasector]
    add     [si], cx
   
    ; 目录放入 0x0200 内存
   
    mov     bx, 0x0200
    call        ReadSec
 
    ; 比较目录中是否有 SYS.img 文件存在
 
    ; mov     cx, WORD [brRootEntries] ; CX:224 在目录的所有文件中寻找
    mov     cx, [fs:rootentriesadd]
   
    mov     ax, fs
    mov     es, ax
   
    mov     di, 0x0200            ; 从目录入口处开始 0x200
.LOOP:
    push        cx                      ; 保护 CX = 224
   
    mov     cx, SystemFileNameLen            ; 8 个文件名称和 3 个扩展名称
    lea     si, [dword SystemFileName]          ;
    push        di                 
    repe        cmpsb                   ; stop compare if cx >0 or the
                                ; first unequal is met(zf=1)!
    pop     di
    je     loadfiledec              ;if zf = 1, jmp LOAD_FAT!(Seek OK!)
    pop     cx
   
    add     di, 0x0020                ; 跳到下一个目录入口
    loop        .LOOP                   ; cx 自动减
 
    call        _NextLine
    lea     si, [dword NotFound]
    call        _pntchr
    jmp     failure
 
    ; 载入文件描述子节
loadfiledec:
    pop     cx ; 有一个 cx 的值没有弹出来
 
    ; 把启动的镜像文件 system.img 文件的起始单元保存起来  
    call        _NextLine
    lea     si, [dword LoadFileDescriptor]
    call        _pntchr
    ; call     _NextLine
 
    mov     dx, [fs:di + 0x001A]               ;the file's first cluster
    lea     si, [dword cluster]
 
    mov     [si], dx                  ; store the first cluster
   
    ; 计算 fat 的大小并保存到 07c00:0x0200(ds:bx)
    xor     ax, ax
    mov     al, BYTE [fs:fatsadd]                ; al:2
    mul     WORD [fs:spfadd]                ; AH:18 = 9*2
    mov     cx, ax                             ; CX:18
 
    ; 读取数据放入到 0x7c00:0x0200 ds:bx
   
    ; mov     ax, WORD [brResCount]          ; AX:1
    mov     ax, WORD [fs:rescountadd]          ; AX:1
 
    mov     bx, 0x0200                          ;
    call        ReadSec                         ; AX:1 CX:18 BX:0200
 
    ; 读取 img 放入 9000:0x1000 处
    mov     ax, SYSSEG
    mov     es, ax
    mov     bx, SYSOFF
    push        bx
 
LOAD_IMAGE:
    call        _NextLine
    lea     si, [dword LoadSystemImage]
    call        _pntchr
   
 
    ; mov     ax, WORD [cluster]       ; cluster to read
    lea     si, [dword cluster]
    mov     ax, [si]                ; cluster to read
    pop     bx                  ; buffer to read into
    call        ClusterLBA           ; convert cluster to LBA
                                ; AX:[cluster] ES:BX[9000:0000](dest)
    xor     cx, cx
   
    mov     cl, BYTE [fs:spcadd] ; CL:1
    call        ReadSec             ; AX:LBA CX:1 BX:0000 ES:0100
    push        bx
   
    ; 计算下一个单元
    lea     si, [dword cluster]
 
    ;mov        ax, WORD [cluster]   ; identify current cluster
    mov     ax, [si]                ; identify current cluster
 
    mov     cx, ax             ; copy current cluster
    mov     dx, ax             ; copy current cluster
    shr     dx, 0x0001            ; divide by two
 
    add     cx, dx             ; sum for (3/2)
    mov     bx, 0x200                ; location of FAT in memory
    add     bx, cx             ; index into FAT
    mov    dx, [fs:bx]            ; read two bytes from FAT
    test        ax, 0x0001
    jnz     .ODD_CLUSTER
 
.EVEN_CLUSTER:
    and     dx, 0000111111111111b    ; take low twelve bits
    jmp     .DONE
 
.ODD_CLUSTER:
    shr     dx, 0x0004            ; take high twelve bits
 
.DONE:
    ; mov     WORD [cluster], dx      ; store new cluster
    lea     si ,[dword cluster]
    mov     [si], dx                ; store new cluster
    cmp     dx, 0x0FF0            ; test for end of file,>=0x0FF0: end or bad!
    jb     LOAD_IMAGE           ; if dx<0x0ff0 (CF=1), jmp Load_image
    DONE:   
    pop     bx                  ; 有一个多出来的 bx 在 stack 里面                        
    ret                        
 
    ; 回到主程序 , 这时 system.img
    ; 已经被装在 0x9000:0x1000 的地方
    ; 只要设置好保护模式的条件就可以跳转了
   
failure:
    call        _NextLine
    lea     si,[dword ErrorMsg]
    call        _pntchr
    call        _NextLine
    hlt
 
文件 system.asm
; ==================================
;;  文件 :    system.asm
;;  作用 :    调用中断
;;    http://blog.youkuaiyun.com/flyback
;;  fly-back@163.com
; ==================================
bits 32
org 0x91000
start:
    mov ax, 0x10   
    mov ds, ax   
    mov ss, ax
    mov esp, 0xfff0
 
    int 0x1
    int 0x0
    hlt
 
连接文件kernel.ld文件
OUTPUT_FORMAT("binary")
ENTRY(start)
SECTIONS
{
 .text 0x90000 : {
    *(.text)
 }
 .data 0x90500 : {
    *(.data)
 }
 .bss : {
 *(.bss)
 }
 
}
编译的build.bat文件
nasm -f aout ../asm/kernel.asm -o ../obj/m.o > error.txt
nasm -f aout ../asm/pnt.asm -o ../obj/pnt.o
nasm -f aout ../asm/readdisk.asm -o ../obj/readdisk.o
nasm -fbin -i../inc -o ../img/SYSTEM.img SYSTEM.ASM
ld -T kernel.ld -s -e start ../obj/m.o ../obj/pnt.o ../obj/readdisk.o -o KERNEL.img
 
编译完成后生成了 :
fatboot.img
KERNEL.IMG
SYSTEM.IMG
然后打开用 winimage 打开 fatboot.img, 把 KERNEL.IMG 和 system.img 放入 fatboot.img 里面
 
制作bochs的配置文件start.txt
# configuration file generated by Bochs
config_interface: textconfig
display_library: win32
megs: 32
romimage: file=E:/操作系统/Bochs-2.1.1/Bochs-2.1.1/BIOS-bochs-latest, address=0xf0000
vgaromimage: E:/操作系统/Bochs-2.1.1/Bochs-2.1.1/VGABIOS-elpin-2.40
boot: floppy
floppya: 1_44="fatboot.img", status=inserted
floppyb: 1_44="none", status=inserted
ata0: enabled=0
ata1: enabled=0
ata2: enabled=0
ata3: enabled=0
parport1: enabled=1, file="parport.out"
com1: enabled=1, dev=""
usb1: enabled=1, ioaddr=0xff80, irq=10
# no sb16
floppy_bootsig_check: disabled=0
vga_update_interval: 300000
keyboard_serial_delay: 250
keyboard_paste_delay: 100000
floppy_command_delay: 500
ips: 1000000
text_snapshot_check: 0
mouse: enabled=0
private_colormap: enabled=0
i440fxsupport: enabled=0
clock: sync=none, time0=local
# no ne2k
newharddrivesupport: enabled=1
# no loader
log: log.txt
logprefix: %t%e%d
debugger_log: debug.txt
panic: action=ask
error: action=report
info: action=report
debug: action=ignore
pass: action=fatal
keyboard_mapping: enabled=0, map=
keyboard_type: mf
user_shortcut: keys=none
# no cmosimage
 
E:/操作系统/Bochs-2.1.1/Bochs-2.1.1 是你安装 bochs 的目录
fatboot.img 是刚才生成的那个文件
和启动文件start.bat
bochsdbg -f start.txt –q
然后双击 Start.bat 启动 bochs
Windows To Go 实战:用辅助工具一键将 Win10 装进 U 盘 Windows To Go 是一种将完整 Windows 系统部署到便携存储设备的技术,让用户在任意电脑上即插即用。其核心原理是把系统镜像写入 U 盘或移动硬盘,并配置引导环境,使其像内置硬盘一样启动运行。这项技术的价值在于系统环境的随身携带与快速恢复,尤其适合系统维护、跨设备办公和应急检修等场景。然而,官方方案存在版本限制、硬件认证门槛高以及性能瓶颈等问题,因此借助第三方辅助工具成为更高效的实践路径。本文从 U 盘选型、镜像获取到一键部署流程,详细讲解如何利用 WTG 辅助工具制作高性能便携 Win10, 阅读详情

相关推荐

RTX 4060笔记本也能跑!保姆级教程:用Ollama在Windows上部署DeepSeek-R1-8B模型

本文详细介绍了如何在RTX 4060笔记本上通过Ollama本地部署DeepSeek-R1-8B模型,提供从环境配置到性能调优的全流程优化指南。针对笔记本用户的显存、散热等问题,给出了量化模型选择、启动参数优化及散热解决方案,帮助用户在消费级硬件上高效运行大语言模型。

weixin_28745067的博客 524

adb命令 -- fastboot命令&OEM解锁

adb命令 -- fastboot命令&OEM解锁,刷机相关

Rpk712的博客 9万+

保姆级教程:用Simulink从零搭建新能源汽车VCU蠕行控制模型(附模型下载)

本文提供了一份详细的Simulink建模教程,指导读者从零开始搭建新能源汽车VCU蠕行控制模型。内容涵盖环境配置、信号定义、蠕行模式使能条件、扭矩控制算法实现及模型验证等关键步骤,特别适合需要将控制算法转化为可执行模型的初学者。教程还包含实用代码示例和常见问题解决方案,帮助开发者快速掌握VCU蠕行控制的Simulink实现技巧。

546

[操作系统] 启动

操作系统启动

weixin_44179561的博客 755

二相混合式步进电机闭环矢量控制simulink仿真(含仿真文件)

在位置跟踪伺服系统中二相混合式步进电机闭环矢量控制simulink仿真

qq_39023633的博客 2万+

Android汽车服务篇(一) CarService

本文主要说明了CarService这一系统服务的启动流程,以及一些关键成员的创建和初始化流程.同时简单介绍了一下客户端是如何获取和使用CarService对象, 如上文介绍的, CarService对象只是获取各个Manager的媒介,它本身并不承担管理传感器.空调等具体的任务.如果要获取车辆的相关信息,如车速, 车内空调温度,诊断信息, 或对车辆进行相关的控制,如升高和降低空调温度,控制座椅和车窗, 调节音量等,就要通过具体的Manager中的API和对应的服务来实现了.

u012514113的专栏 8145

实验10 硬盘DMA编程

导读:   新一篇: 实验11 多任务和多线程   采用PIO方式访问硬盘,硬盘扇区数据的读写完全由CPU通过IN、OUT指令执行,一个扇区占512字节,需要256次I/O操作,占用CPU资源。读取硬盘扇区时,每次I/O操作包括一个IN指令和一个内存写操作,CPU先读取16位数据到AX中,再将16位数据写入到内存中。写入硬盘扇区时,每次I/O操作则包括一个内存读操作和一个OUT指令。   使用DM

xu的blog 3627

JSSIP实战:5分钟搞定WebRTC电话功能(附完整代码示例)

本文通过JSSIP库实战演示如何在Web应用中快速集成WebRTC电话功能。文章提供了从环境准备、SIP服务器连接到完整代码示例的详细步骤,涵盖用户注册、拨号接听、媒体流处理等核心环节,并针对常见问题给出排查方案,帮助开发者高效实现网页端实时语音通信。

u8v9w0x1y的博客 517

80x86保护模式系列教程(4)实模式与保护模式切换实例

四.实模式与保护模式切换实例本文介绍两个实现实模式与保护模式切换的实例,通过他们说明如何实现实模式与保护模式的切换, 也说明保护模式下的80386及其编程。 演示实模式和保护模式切换的实例(实例一)实例一的逻辑功能是,以十六进制数的形式显示从内存地址110000H开始的256个字节的值。本实例指定该内存区域的目的仅仅是想说明切换到保护模式的必要性,因为在实模式下不能访问该指定内存区

Liang Tang's 专栏 3930

【图像超分】论文复现:新手入门必备!Pytorch实现SRGAN!手把手详细教程!代码注释详尽!可用于训练自己的数据集!实时验证模型性能!绘制PSNR曲线图!附训练好的各放大倍数的模型权重文件!

【图像超分】论文精读:SRResNet/SRGAN【图像超分】论文复现:万字长文!Pytorch实现SRResNet代码修改无报错!踩坑全记录!适合各种深度学习新手!帮助你少走弯路!附修改后的代码和PSNR最优的模型权重文件!请配合上述论文精读文章使用,效果更佳!与原论文描述不一样的实现部分,也即可以修改的部分数据集使用:论文中是ImageNet随机选35000张图像,本文是VOC2012数据集16700张图像。数据集预处理:裁剪大小不同,论文是96×96,本文是88×88。

主要更新底层视觉(去噪、超分等)相关的科研内容,形式为【论文精读】+【论文复现】 6852

模型预测控制(MPC)算法介绍

模型预测控制(Model Predictive Control,MPC)是一种先进的控制策略,广泛应用于工业过程控制、机器人控制、电力系统等领域。它基于系统的模型,通过滚动优化来预测系统未来的行为,并据此确定当前的最优控制输入。

AI的内部世界的博客 7170

进入保护模式总结

1.最主要的就是那个jmp dword,一切都是为了Jmp做准备 2.int 13h读取扇区,既可以读硬盘,又可以读软盘,应该是两个的驱动器号不同(这个还没搞清楚,现在只会读软盘)。用硬盘映像的时候,总是说找不到引导设备,不知道是哪儿的参数错了。 一些细节: >cl是读取的扇区号,1就是第1个扇区,并不是从0算起。 >kernel.s生成的就只有16B,所以只读取16字节。(其他的好像是0

A1157599735的专栏 1311

构建企业级AI税务顾问:优化税收策略与合规

本文深入探讨了构建企业级AI税务顾问的重要性及其在实际应用中的价值。通过分析当前税务领域的挑战和问题,本文详细介绍了AI税务顾问的基本原理、技术架构、核心功能以及实践应用。文章以逐步分析的方式,从背景介绍、核心概念与联系、算法原理讲解、系统分析与架构设计、项目实战到最佳实践与展望,系统性地展示了如何利用AI技术优化税收策略并确保税务合规。文章旨在为企业和税务从业者提供实用的指导,推动AI在税务领域的创新与发展。在当前全球经济一体化的背景下,企业面临着越来越复杂的税务环境。首先,税收法规的复杂性日益增加。

AI天才研究院 1153

strcpy漏洞分析

前段时间发现一个有趣的代码: char str[1]; strcpy(str, "wwwwwwwwwwwwwwwwwwwww"); printf("%s", str); getchar();运行结果:大家可以看到,我使用strcpy向一个长度为1的数组赋一个长度为21的字符,并且被赋值了,还被打印了出来!那么下面来解释一下为什么会产生这样的原因!在CPU看来内存是连续的,是一组线性的地址空...

17岁boy的博客 2015

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

WINDOWS常见问题的最佳解决方案

WINDOWS常见问题的最佳解决方案1、电脑为什么关机后又自动重启动?答: 电脑关机后自动重启的原因最常见的是由快速关机引起的。解决办法是:①开始/运行/输入:msconfig/确定/系统实用配置程序/高级/选中“禁用快速关机”/重新启动电脑。 ②如果还不能解决,看看是否有驱动程序或硬件错误。电脑在正常关闭时却自动重启,一般是由于主板电源管理出现问题所致。有些主板的电源管理部件,由于受布线设计和零

洪虎专栏 2万+

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

《Linux系统编程之进程基础》【进程切换 + 进程调度】

进程切换:(也称“进程上下文切换”)是指 CPU 从当前正在执行的进程,切换到另一个需要执行的进程的过程。它是操作系统实现“多任务并发”的核心机制 —— 即便在单核 CPU 上,通过频繁的进程切换,也能让多个进程 “看似同时运行”进程上下文“进程上下文”硬件上下文:CPU 寄存器中存储的临时数据。程序计数器 PC—— 记录下一条要执行的指令地址通用寄存器—— 存储进程运行中的临时变量程序状态字 PSW—— 记录 CPU 状态如中断屏蔽位软件上下文进程的地址空间(代码、数据、堆、栈)

2509_93923299的博客 820

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

诊断之美-一个经典的调试例子

这是一个我看到过的一个比较经典的系统调试分析过程,牵涉到整个片上系统的方方面面的知识.写下来免得以后忘了. 症状:上电后,处理器能够出reset,并跳转到第一条指令,但是BIOS跑到某些Legacy模块,,比如8259,8254初始化的地方,会死掉. 初步分析:改动bios代码,在处理器还能动的时候去访问那些会导致死机模块的寄存器,发现一访问就死机.通常如果一个模块的寄存器读取数据不正确的

jdygrdzh的专栏 1220

操作系统引导--从实模式到保护模式

从开始到保护--系统开机引导 ------没有一个文档能写的通俗易懂,我希望写出来。 开机引导和实模式: 两个星期加上假期吐血整理,所述为计算机的开机引导,其中包括一系列计算机内存设置等等,由于没有老师教,本人理解可能还是有点错误,希望错误的地方看的博友们能帮忙指出来,共同学习,谢谢! 目前正在看linux0.11内核源代码,参考资料极其环境配置后面会说出来。 我们的

xyjikl 3361

操作系统16----bootloader保护模式源码分析

bootloader保护模式源码分析 环境准备 安装VirtualBox 虚拟机软件 安装Ubuntu镜像 项目组成结构 系统启动过程​​ BIOS启动过程 bootloader启动过程 qemu和gdb调试ucore bootloader 进入保护模式过程 以清华大学u...

大魔王 1631

Process memory buffer分配机制——show buffers相关

思科设备巡检过程中,往往要求工程师注意show buffers输出的failures及misses,出于对buffer以及其中各项参数的意义的好奇,特进行了探究,遂编写此文档。1.路由器数据转发机制1.1 转发机制概述 (1)Process Switching 基于进程的转发,数据流量的处理需要依赖RP(Routing Pro...

weixin_34318956的博客 1073

保护模式下寻址

 保护模式下寻址 刺猬@http://blog.youkuaiyun.com/littlehedgehog 网上看到的一强帖,不转不行了,牛人啊,把这段代码拿捏的相当到位 括号中是我的加注 段机制轻松体验[内存寻址]实模式下的内存寻址:让我们首先来回顾实模式下的寻址方式段首地址×16+偏移量 = 物理地址为什么要×16?因为在8086CPU中,地址线是20位,但寄存器是16位的,最高寻

刺猬小屋 1万+

自己动手写操作体统 pmtest1.asm 详细解释

本文来自优快云博客,转载请标明出处:http://blog.youkuaiyun.com/wangshenwq/archive/2008/09/14/2927636.aspx 段机制轻松体验  内存寻址:  实模式下的内存寻址:  让我们首先来回顾实模式下的寻址方式  段首地址×16+偏移量 = 物理地址  为 什么要×16?因为在8086CPU中,地址线是20位,但寄存器是16位的,最高寻

onejian的专栏 1149

切换到保护模式

.model large.586p;******************jump macro selecter,offsetv   ;16位偏移的段间直接转移指令的宏定义  db 0eah  dw offsetv  dw selecterendm;******************h_line macro x,y,re,col  ;写屏幕上任一行像素点       local flg1,flg2

z_long的专栏 521
上一篇: 真的很伤心 - 看到龙芯和麒麟的新闻
下一篇: 不要过劳死 -到底我们在为了什么而操劳,为了钱吗?还是为了快乐?
魔芋
博客等级 码龄26年 37粉丝 71原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值