+ -
当前位置:首页 → 问答吧 → 一段进入保护模式的程序,那位大侠给看看那有问题?

一段进入保护模式的程序,那位大侠给看看那有问题?

时间:2003-06-26

来源:互联网

源程序
------------------------------------------------------
#define CR0_PE 1

.text
.code16
.globl _start
_start:
jmp start0
nop
mesg1:
.ascii "Loading...... "
mesg2:
.ascii "Ready........ "
##################### idt ########################
idt:
.word 0
.word 0, 0
##################### gdt ########################
.align 16
gdt:
.word 0, 0
.byte 0, 0x00, 0x00, 0
bootcodeseg = . - gdt
.word 0xffff, 0
.byte 0, 0x9e, 0x4f, 0
bootdataseg = . - gdt
.word 0xffff, 0
.byte 0, 0x92, 0x4f, 0
videoseg = . - gdt
.word 0x3999, 0x8000
.byte 0x0b, 0x92, 0x00, 0x00
bootrealseg = . - gdt
.word 0xffff, 0
.byte 0, 0x9e, 0x00, 0
bootrealdata = . - gdt
.word 0xffff, 0
.byte 0, 0x92, 0x00, 0
gdtlen = . - gdt
.align 16
gdtarg:
.word gdtlen-1 /* limit */
.long 0 /* physical addr, will be inserted */
ourseg: .word 0 /* real mode code and data segment */
stkseg: .word 0 /* real mode stack segment */
stkdif: .long 0 /* diff. between real and prot sp */
#
# start of code
#
start0:
mov %cs, %ax /* don't trust values of ds, es or ss */
mov %ax, %ds
mov %ax, %es
mov %ax, %ss
mov $0xfffc, %sp

xor %ax, %ax /* in particular ah = 0 */
int $0x13

call clrscr
movw $mesg1,%bp
call prt_msg
call get_key
call clrscr
call gdt_fixup
movw $mesg2,%bp
call prt_msg
call get_key
call clrscr
call real_to_prot
loop:
jmp loop
gdt_fixup:
.code16
pushw %ax
pushw %dx

xorl %eax, %eax
mov %cs, %ax
mov %ax, ourseg
/* sort out stuff for %ss != %ds */
movw %ss, %dx
movw %dx, stkseg
subw %ax, %dx
shll $16, %edx
shrl $12, %edx
movl %edx, stkdif

/* fix up GDT entries for bootstrap */
mov %ax, %dx
shll $4, %eax
shr $12, %dx

#define FIXUP(gdt_index) \
movw %ax, gdt+gdt_index+2; \
movb %dl, gdt+gdt_index+4

FIXUP(bootcodeseg)
FIXUP(bootrealseg)
FIXUP(bootdataseg)

/* fix up GDT pointer */
addl $gdt, %eax
movl %eax, gdtarg+2

pop %dx
pop %ax
ret

real_to_prot:
.code16
pushl %eax
cli

lidt %cs:idt
lgdt %cs:gdtarg /* Global descriptor table */

movl %cr0, %eax
or $CR0_PE, %ax
movl %eax, %cr0 /* Enter 'protected mode' */
ljmp $bootcodeseg, $1f /* Jump into a 32bit segment */
1:
.code32
dbg:
jmp dbg
/* Set all the segment registers to map the same area as the code */
mov $bootdataseg, %eax
mov %ax, %ds
mov %ax, %es
mov %ax, %ss
addl stkdif, %esp /* Allow for real %ss != %ds */

mov $videoseg, %eax
mov %ax, %gs
movw $0x741,0x000b8000
spin:
jmp spin
popl %eax
ret

prt_msg:
.code16
movb $0x13,%ah
movb $0x00,%al
movw $0x0007,%bx
movw $0x14,%cx
movw $0x0000,%dx
int $0x10
ret
get_key:
.code16
movb $0x00,%ah
int $0x16
ret
clrscr:
.code16
movw $0x0600,%ax
movw $0x0000,%cx
movw $0x174f,%dx
movb $0x0, %bh
int $0x10
ret


.org 510
boot_flag:
.word 0xAA55
------------------------------------------------------
中间那个ljmp是进入32位代码,我加了个死循环在那里,每次
执行到这里系统就重启了,应该是发生异常了。

makefile:
------------------------------------------------------
boot : bootp.out
objcopy -S -O binary bootp.out boot
bootp.out : bootp.o
ld -nostdlib -static -N -e _start -Ttext 0x7c00 -o bootp.out : bootp.o
bootp.o : _bootp.S
as -o bootp.o _bootp.S
_bootp.S : bootp.S
cc -o _bootp.S -E bootp.S
clean :
rm -rf bootp.o bootp.out _bootp.S
install :
dd bs=512 if=boot of=/dev/fd0
------------------------------------------------------

执行make编译,make clean删除中间文件,make install 写到软盘

执行说明:
用生成的软盘启动,看到打印字符串按任意键继续

程序功能:
进入保护模式并使用显存地址0x000b:8000显示一个白色的A

问题:
一执行进入32位代码的跳转系统就重启,怎么也没搞明白为什么。
另:
大家有知道什么debug工具可以跟踪这种程序?

作者: kakuyou   发布时间: 2003-06-26

源程序
代码:
#define    CR0_PE 1

        .text
        .code16
        .globl _start
_start:
        jmp start0
        nop 
mesg1:
        .ascii "Loading...... "
mesg2:
        .ascii "Ready........ "
##################### idt ########################
idt:
        .word 0
        .word 0, 0
##################### gdt ########################
        .align 16
gdt:
        .word   0, 0
        .byte   0, 0x00, 0x00, 0
bootcodeseg = . - gdt
        .word   0xffff, 0
        .byte   0, 0x9e, 0x4f, 0
bootdataseg = . - gdt
        .word   0xffff, 0
        .byte   0, 0x92, 0x4f, 0
videoseg = . - gdt
        .word 0x3999, 0x8000
        .byte 0x0b, 0x92, 0x00, 0x00
bootrealseg = . - gdt
        .word   0xffff, 0
        .byte   0, 0x9e, 0x00, 0
bootrealdata = . - gdt
        .word   0xffff, 0
        .byte   0, 0x92, 0x00, 0
gdtlen = . - gdt
        .align  16
gdtarg:
        .word   gdtlen-1 /* limit */
        .long   0 /* physical addr, will be inserted */
ourseg: .word   0 /* real mode code and data segment */
stkseg: .word   0 /* real mode stack segment */
stkdif: .long   0 /* diff. between real and prot sp */
#
# start of code
#
start0:
        mov     %cs, %ax /* don't trust values of ds, es or ss */
        mov     %ax, %ds
        mov     %ax, %es
        mov     %ax, %ss
        mov     $0xfffc, %sp

        xor     %ax, %ax /* in particular ah = 0 */
        int     $0x13

        call clrscr
        movw $mesg1,%bp
        call prt_msg
        call get_key
        call clrscr
        call gdt_fixup
        movw $mesg2,%bp
        call prt_msg
        call get_key
        call clrscr
        call real_to_prot
loop:
        jmp loop
gdt_fixup:
        .code16
        pushw   %ax
        pushw   %dx

        xorl    %eax, %eax
        mov     %cs, %ax
        mov     %ax, ourseg
        /* sort out stuff for %ss != %ds */
        movw    %ss, %dx
        movw    %dx, stkseg
        subw    %ax, %dx
        shll    $16, %edx
        shrl    $12, %edx
        movl    %edx, stkdif

        /* fix up GDT entries for bootstrap */
        mov     %ax, %dx
        shll    $4, %eax
        shr     $12, %dx

#define FIXUP(gdt_index) \
        movw    %ax, gdt+gdt_index+2; \
        movb    %dl, gdt+gdt_index+4

        FIXUP(bootcodeseg)
        FIXUP(bootrealseg)
        FIXUP(bootdataseg)

        /* fix up GDT pointer */
        addl    $gdt, %eax
        movl    %eax, gdtarg+2  
        
        pop     %dx
        pop     %ax
        ret

real_to_prot:
        .code16
        pushl   %eax
        cli

        lidt    %cs:idt
        lgdt    %cs:gdtarg /* Global descriptor table */

        movl    %cr0, %eax
        or      $CR0_PE, %ax
        movl    %eax, %cr0 /* Enter 'protected mode' */
        ljmp    $bootcodeseg, $1f       /* Jump into a 32bit segment */
1:
        .code32
dbg:
        jmp dbg
        /* Set all the segment registers to map the same area as the code */
        mov     $bootdataseg, %eax
        mov     %ax, %ds
        mov     %ax, %es
        mov     %ax, %ss
        addl    stkdif, %esp /* Allow for real %ss != %ds */
        
        mov $videoseg, %eax
        mov %ax, %gs
        movw $0x741,0x000b8000
spin:
        jmp spin
        popl    %eax
        ret

prt_msg:
        .code16
        movb $0x13,%ah
        movb $0x00,%al
        movw $0x0007,%bx
        movw $0x14,%cx
        movw $0x0000,%dx
        int $0x10
        ret
get_key:
        .code16
        movb $0x00,%ah
        int $0x16
        ret
clrscr:
        .code16
        movw $0x0600,%ax
        movw $0x0000,%cx
        movw $0x174f,%dx
        movb $0x0, %bh
        int $0x10
        ret


        .org 510
boot_flag:
        .word 0xAA55
make文件
代码:
boot : bootp.out
        objcopy -S -O binary bootp.out boot
bootp.out : bootp.o
        ld -nostdlib -static -N -e _start -Ttext 0x7c00 -o bootp.out bootp.o
bootp.o : _bootp.S
        as -o bootp.o _bootp.S
_bootp.S : bootp.S
        cc -o _bootp.S -E bootp.S
clean :
        rm -rf bootp.o bootp.out _bootp.S
install :
        dd bs=512 if=boot of=/dev/fd0

作者: kakuyou   发布时间: 2003-06-26

全局描述符设得对吗?

作者: eax   发布时间: 2003-07-01

热门下载

更多