隨筆-65  評論-68  文章-4  trackbacks-0

          今天的程序編寫倒不是很長時間,但是DEBUG花了我好長時間,具體前幾次崩潰的原因沒有找出來,但是最終可以運行了。
          截個圖片,然后是匯編程序。



          org 0x100
          [bits 16]
          jmp loaderStart

          _GRAPH_SEG_OFFSET_ equ 0xb800

          _RootEntCnt_ equ 0xe0

          BS_OEMName db 'XXXXXXXX'
          BPB_BytsPerSec dw 0x200
          BPB_SecPerClus db 1
          BPB_RsvdSecCnt dw 1
          BPB_NumFATs db 2
          BPB_RootEntCnt dw _RootEntCnt_
          BPB_totSec16 dw 0xb40
          BPB_Media db 0xf0
          BPB_FATSz16 dw 9
          BPB_SecPerTrk dw 0x12
          BPB_NumHeads dw 2
          BPB_HiddSec dd 0
          BPB_totSec32 dd 0
          BS_DrvNum db 0
          BS_Reserved1 db 0
          BS_BootSig db 0x29
          BS_VolID dd 0
          BS_VolLab db '11111111111'
          BS_FileSysType db 'FAT12?? '

          parameters:
          ?screenPo dd 0
          ?STR_LEN equ 12
          ?bootStr db 'Loading...? '
          ?noLoaderStr db 'No Kernel...'
          ?ready db 'Ready?????? '
          ?KernelBase equ 0x8000
          ?KernelOffset equ 0x0
          ?rootEntryNum db _RootEntCnt_
          ?loaderName db 'KERNEL? BIN'


          loaderStart:
          ?mov ax,cs
          ?mov ds,ax
          ?mov es,ax
          ?mov ss,ax
          ?mov sp,0100
          ?mov ax,_GRAPH_SEG_OFFSET_
          ?mov gs,ax
          ?
          ?mov dh,0
          ?call displayStr
          ?
          ?xor ah,ah
          ?mov dl,[BS_DrvNum]
          ?int 0x13
          ?
          ?mov ax,KernelBase
          ?mov es,ax
          ?mov bx,0
          ?mov ax,19
          ?mov cl,14
          ?call readSector
          ?
          ?
          ?xor edi,edi
          ?
          anotherFile:
          ?xor esi,esi
          ?cmp byte [rootEntryNum],0
          ?je noLoader
          ?
          nextChar:
          ?mov al,byte [es:edi]
          ?cmp byte [ds:loaderName+si],al
          ?jne notThisFile
          ?cmp si,10
          ?je found
          ?inc esi
          ?inc edi
          ?jmp nextChar
          ?
          ?notThisFile:
          ?shr edi,5
          ?inc edi
          ?shl edi,5
          ?dec byte [rootEntryNum]
          ?jmp anotherFile
          ?
          noLoader:
          ?mov dh,1
          ?call displayStr
          ?jmp $
          ?
          found:
          ?mov dh,2
          ?call displayStr
          ?
          ?mov ax,word [es:edi+(0x10)]
          ?mov cl,1
          ?
          ?push ax
          ?mov ax,KernelBase
          ?mov es,ax
          ?mov ebx,KernelOffset
          ?pop ax
          ?
          ?readEntry:
          ?
          ?cmp ax,0xfff
          ?je readEnd
          ?push ax
          ?add ax,19+14-2
          ?call readSector
          ?pop ax
          ?
          ?add ebx,512
          ?call getFATEntry
          ?
          ?jmp readEntry
          ?readEnd:
          ?
          ?jmp toProtectMode

          displayStr:
          ?; dh: String index
          ?push cx
          ?push ax
          ?push bx
          ?push esi
          ?push edi
          ?mov cx,STR_LEN
          ?mov edi,dword [screenPo]
          ?mov esi,bootStr
          ?xor eax,eax
          ?mov al,dh
          ?mov bl,STR_LEN
          ?mul bl
          ?add esi,eax
          ?.1:
          ?lodsb
          ?mov [gs:edi],al
          ?inc edi
          ?inc edi
          ?loop .1
          ?
          ?mov dword [screenPo],edi
          ?pop edi
          ?pop esi
          ?pop bx
          ?pop ax
          ?pop cx
          ?ret

          readSector: ;ax: starting sector cl:number of sectors
          ?; ah 0x2????????? al:number of sector to read
          ?; ?????bx: es:bx
          ?; ch:cylinder???cl:start sector
          ?; dh:head?num???dl:Drive
          ?push bp
          ?mov bp,sp
          ?push cx
          ?push dx
          ?push ax
          ?
          ?mov dl,[BPB_SecPerTrk]
          ?div dl
          ?mov cl,ah
          ?inc cl
          ?
          ?mov ch,al
          ?shr ch,1
          ?
          ?mov dh,al
          ?and dh,1
          ?
          ?mov dl,byte [BS_DrvNum]
          ?
          ?.1:
          ?mov ah,2
          ?mov al,byte [bp-2]
          ?int 0x13
          ?jc .1
          ??
          ?pop ax
          ?pop dx
          ?pop cx
          ?pop bp
          ?ret
          ?
          getFATEntry:
          ?FATBaseInMem equ 0x7000
          ?;ax is the entry number
          ?;return ax is the next entry
          ?
          ?push es
          ?push bx
          ?push dx
          ?push cx
          ?
          ?mov bx,FATBaseInMem
          ?mov es,bx
          ?
          ?mov bx,3
          ?mul bx ;dx:ax
          ?mov bx,2
          ?div bx ;dx is the rest
          ?push dx
          ?
          ?xor dx,dx
          ?mov bx,[BPB_BytsPerSec]
          ?div bx
          ?mov cl,2
          ?xor bx,bx
          ?add ax,1
          ?call readSector
          ?mov bx,dx; mov byte index
          ?
          ?pop dx
          ?xor ax,ax
          ?cmp dx,0
          ?jne oddPart
          ?

          ?mov ax,word [es:bx]
          ?and ax,0x0fff
          ?
          ?jmp after
          ?oddPart:
          ?
          ?mov ax,word [es:bx]
          ?shr ax,4


          ?after:
          ?pop cx
          ?pop dx
          ?pop bx
          ?pop es
          ?
          ?ret
          ?
          ?
          toProtectMode:
          ?jmp start
          ?
          %macro Descriptor 3
          ?dw %2 & 0xffff
          ?dw %1 & 0xffff
          ?db (%1 >> 16) & 0xff
          ?dw ((%2 & 0x0f0000) >> 8) | (%3 & 0xf0ff)
          ?db (%1 >> 24) & 0xff
          %endmacro

          DummyGDT: Descriptor 0,0,0
          CodeGDT: Descriptor 0,0xfffff,1100000010011010b
          DataGDT: Descriptor 0,0xfffff,1000000010010010b
          ScreenGDT: Descriptor 0xb8000,0xffff,0000000010010010b

          GDTPtr dw $-DummyGDT-1
          ?dd 0x9000*0x10+DummyGDT

          CodeSelector equ CodeGDT-DummyGDT
          DataSelector equ DataGDT-DummyGDT
          ScreenSelector equ ScreenGDT-DummyGDT

          start:
          ?call killMotor
          ?cli
          ?mov dh,2
          ?call displayStr
          ?
          ?lgdt [GDTPtr]
          ?
          ?in al,0x92
          ?or al,10b
          ?out 0x92,al
          ?
          ?mov eax,cr0
          ?or eax,1
          ?mov cr0,eax
          ?
          ?jmp dword CodeSelector:(0x9000*0x10+ProtectMode)

          killMotor:
          ?push dx
          ?mov dx,0x3f2
          ?mov al,0
          ?
          ?out dx,al
          ?pop dx
          ?ret


          [bits 32]
          ProtectMode:
          ?mov ax,ScreenSelector
          ?mov gs,ax
          ?xor edi,edi
          ?.again:
          ?inc byte [gs:edi]
          ?jmp .again

          posted on 2007-01-18 16:22 小爽 閱讀(746) 評論(5)  編輯  收藏 所屬分類: 我的經驗我的操作系統

          評論:
          # re: 今天的Loader實驗總算DEBUG完成[未登錄] 2007-03-14 14:41 | Sam
          請教個問題:
          我在Virtual PC 上安裝了DOS7.1。 然后把一個于淵chapter3/a/pmtest1.com放在上面運行。結果出錯。
          我發現是在lgdt那句的問題。 你有什么建議嗎?
          我的MSN:sam_code@hotmail.com  回復  更多評論
            
          # re: 今天的Loader實驗總算DEBUG完成 2007-03-14 15:17 | wilson
          @Sam
          應該是因為DOS版本太高的緣故吧。一般都是用DOS 6.22。安裝一下DOS6.22試一下。
          這僅僅是猜測啊。因為很有可能微軟的DOS7能夠進入使用保護模式了。  回復  更多評論
            
          # re: 今天的Loader實驗總算DEBUG完成 2008-05-16 12:45 | guapibai
          @wilson
          你是不是單步調試了阿,如果是的話可能有問題,還有最好dos5.0進行實驗。  回復  更多評論
            
          # re: 今天的Loader實驗總算DEBUG完成[未登錄] 2008-12-12 10:49 | st
          那是因為在DOS下只能實現實模式,不能跳轉到保護模式
          解決方法:
          將pmtest1.asm編譯成.bin文件放在引導盤上運行.  回復  更多評論
            
          # re: 今天的Loader實驗總算DEBUG完成[未登錄] 2010-08-23 21:54 | YBW
          那段代碼本就沒有返回DOS的語句!!!  回復  更多評論
            
          主站蜘蛛池模板: 张家港市| 西峡县| 松溪县| 玉屏| 日喀则市| 五原县| 贵溪市| 凭祥市| 和硕县| 佛教| 甘孜县| 普格县| 淮北市| 日照市| 裕民县| 和田市| 东阳市| 黎平县| 方正县| 平昌县| 河北区| 常宁市| 和平区| 韶山市| 金昌市| 呼图壁县| 巴南区| 镇康县| 太白县| 英吉沙县| 融水| 克拉玛依市| 即墨市| 东兴市| 驻马店市| 宁津县| 黄骅市| 桃园市| 南郑县| 郴州市| 舒城县|