主题:高手看看这两个程序有什么区别??我实在找不出了
[color=008080][color=0000FF][color=FF0000];从实模式转换到保护模式 ,然后在屏幕上打印一个"Hello,welcome to my S_OS"
; 宏 ------------------------------------------------------------------------------------------------------
;
; 描述符
; usage: Descriptor Base, Limit, Attr
; Base: dd
; Limit: dd (low 20 bits available)
; Attr: dw (lower 4 bits of higher byte are always 0)
;%macro Descriptor 3
; dw %2 & 0FFFFh ; 段界限 1 (2 字节)
; dw %1 & 0FFFFh ; 段基址 1 (2 字节)
; db (%1 >> 16) & 0FFh ; 段基址 2 (1 字节)
; dw ((%2 >> 8) & 0F00h) | (%3 & 0F0FFh) ; 属性 1 + 段界限 2 + 属性 2 (2 字节)
; db (%1 >> 24) & 0FFh ; 段基址 3 (1 字节)
;%endmacro ; 共 8 字节
;
;
%include "pm.inc"
org 0100h
jmp start
;GDT
[SECTION .gdt]
LABEL_GDT: Descriptor 0, 0, 0
LABEL_CODE32: Descriptor 0, SEG_CODE32_LEN-1, 4098h
LABEL_VIDEO32: Descriptor 0B8000h, 0ffffh, 92h
LABEL_DATA32: Descriptor 0, SEG_DATA32_LEN-1, 92h
;GDT_48
gdt_len EQU $-LABEL_GDT
gdt_48 dw gdt_len-1
dd 0
;GDT选择子
code32 EQU LABEL_CODE32-LABEL_GDT
video32 EQU LABEL_VIDEO32 -LABEL_GDT
data32 EQU LABEL_DATA32 - LABEL_GDT
[SECTION .data1]
ALIGN 32
[BITS 32]
LABEL_SEG_DATA32:
BootMessage: db "hello",0
offsetBootMessage db BootMessage -$$
SEG_DATA32_LEN EQU $- LABEL_SEG_DATA32
[SECTION .s16]
[BITS 16]
start:
mov ax , cs
mov ds , ax
mov es , ax
mov ss , ax
mov sp , 0100h
;初始化代码段描述符
xor eax , eax
mov ax , cs
shl eax , 4
add eax , LABEL_SEG_CODE32
mov word [LABEL_CODE32+2] , ax
shr eax , 16
mov byte [LABEL_CODE32+4] , al
mov byte [LABEL_CODE32+7] , ah
;初始化数据段描述符
xor eax , eax
mov ax , ds
shl eax , 4
add eax , LABEL_SEG_DATA32
mov word [LABEL_DATA32+2] , ax
shr eax , 16
mov byte [LABEL_DATA32+4] , al
mov byte [LABEL_DATA32+7] , ah
;加载GDTR
xor eax , eax
mov ax , ds
shl eax , 4
add eax , LABEL_GDT
mov dword [gdt_48+2] , eax
lgdt [gdt_48]
;关中断
cli
;开A20地址线
in al, 92h
or al, 00000010b
out 92h, al
;置cr0的pe位
mov eax , cr0
or eax , 1
mov cr0 ,eax
;开中断
;sti
;jmp 进入保护模式
jmp dword code32:0
[SECTION .s32]
[BITS 32]
LABEL_SEG_CODE32:
mov ax , data32
mov ds , ax
mov ax , video32
mov gs , ax
mov ah , 0ch
xor esi , esi
xor edi , edi
mov esi , offsetBootMessage
mov edi , (80*10+0)*2
cld
sec:
lodsb
test al ,al
jz fir
mov [gs:edi] , ax
add edi , 2
jmp sec
fir:
jmp $
SEG_CODE32_LEN EQU $-LABEL_SEG_CODE32[/color][/color][/color]
第二个程序:
[color=008000]; ==========================================
; pmtest2.asm
; 编译方法:nasm pmtest2.asm -o pmtest2.com
; ==========================================
%include "pm.inc" ; 常量, 宏, 以及一些说明
org 0100h
jmp LABEL_BEGIN
[SECTION .gdt]
; GDT
; 段基址, 段界限 , 属性
LABEL_GDT: Descriptor 0, 0, 0 ; 空描述符
LABEL_DESC_CODE32: Descriptor 0, SegCode32Len - 1, DA_C + DA_32 ; 非一致代码段, 32
LABEL_DESC_DATA: Descriptor 0, DataLen - 1, DA_DRW ; Data
LABEL_DESC_VIDEO: Descriptor 0B8000h, 0ffffh, DA_DRW ; 显存首地址
; GDT 结束
GdtLen equ $ - LABEL_GDT ; GDT长度
GdtPtr dw GdtLen - 1 ; GDT界限
dd 0 ; GDT基地址
; GDT 选择子
SelectorCode32 equ LABEL_DESC_CODE32 - LABEL_GDT
SelectorData equ LABEL_DESC_DATA - LABEL_GDT
SelectorVideo equ LABEL_DESC_VIDEO - LABEL_GDT
; END of [SECTION .gdt]
[SECTION .data1] ; 数据段
ALIGN 32
[BITS 32]
LABEL_DATA:
;SPValueInRealMode dw 0
; 字符串
PMMessage: db "In Protect Mode now. ^-^", 0 ; 进入保护模式后显示此字符串
OffsetPMMessage equ PMMessage - $$
DataLen equ $ - LABEL_DATA
; END of [SECTION .data1]
[SECTION .s16]
[BITS 16]
LABEL_BEGIN:
mov ax, cs
mov ds, ax
mov es, ax
mov ss, ax
mov sp, 0100h
; 初始化 32 位代码段描述符
xor eax, eax
mov ax, cs
shl eax, 4
add eax, LABEL_SEG_CODE32
mov word [LABEL_DESC_CODE32 + 2], ax
shr eax, 16
mov byte [LABEL_DESC_CODE32 + 4], al
mov byte [LABEL_DESC_CODE32 + 7], ah
; 初始化数据段描述符
xor eax, eax
mov ax, ds
shl eax, 4
add eax, LABEL_DATA
mov word [LABEL_DESC_DATA + 2], ax
shr eax, 16
mov byte [LABEL_DESC_DATA + 4], al
mov byte [LABEL_DESC_DATA + 7], ah
; 为加载 GDTR 作准备
xor eax, eax
mov ax, ds
shl eax, 4
add eax, LABEL_GDT ; eax <- gdt 基地址
mov dword [GdtPtr + 2], eax ; [GdtPtr + 2] <- gdt 基地址
; 加载 GDTR
lgdt [GdtPtr]
; 关中断
cli
; 打开地址线A20
in al, 92h
or al, 00000010b
out 92h, al
; 准备切换到保护模式
mov eax, cr0
or eax, 1
mov cr0, eax
; 真正进入保护模式
jmp dword SelectorCode32:0 ; 执行这一句会把 SelectorCode32 装入 cs, 并跳转到 Code32Selector:0 处
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
[SECTION .s32]; 32 位代码段. 由实模式跳入.
[BITS 32]
LABEL_SEG_CODE32:
mov ax, SelectorData
mov ds, ax ; 数据段选择子
mov ax, SelectorVideo
mov gs, ax ; 视频段选择子
; 下面显示一个字符串
mov ah, 0Ch ; 0000: 黑底 1100: 红字
xor esi, esi
xor edi, edi
mov esi, OffsetPMMessage ; 源数据偏移
mov edi, (80 * 10 + 0) * 2 ; 目的数据偏移。屏幕第 10 行, 第 0 列。
cld ;清方向位
.1:
lodsb ;[si]->ax
test al, al
jz .2
mov [gs:edi], ax
add edi, 2
jmp .1
.2: ; 显示完毕
jmp $
SegCode32Len equ $ - LABEL_SEG_CODE32
; ------------------------------------------------------------------------[/color]
这两个程序 ,两个程序都用nasmw.exe编译通过,但是第一个程序在纯dos下运行,会出现一个 "处理器运到一个随机的错误", 第二个程序正常运行,在屏幕上出现 “In Protect Mode now. ^-^”.大家帮我找找两个程序的不同啊?
; 宏 ------------------------------------------------------------------------------------------------------
;
; 描述符
; usage: Descriptor Base, Limit, Attr
; Base: dd
; Limit: dd (low 20 bits available)
; Attr: dw (lower 4 bits of higher byte are always 0)
;%macro Descriptor 3
; dw %2 & 0FFFFh ; 段界限 1 (2 字节)
; dw %1 & 0FFFFh ; 段基址 1 (2 字节)
; db (%1 >> 16) & 0FFh ; 段基址 2 (1 字节)
; dw ((%2 >> 8) & 0F00h) | (%3 & 0F0FFh) ; 属性 1 + 段界限 2 + 属性 2 (2 字节)
; db (%1 >> 24) & 0FFh ; 段基址 3 (1 字节)
;%endmacro ; 共 8 字节
;
;
%include "pm.inc"
org 0100h
jmp start
;GDT
[SECTION .gdt]
LABEL_GDT: Descriptor 0, 0, 0
LABEL_CODE32: Descriptor 0, SEG_CODE32_LEN-1, 4098h
LABEL_VIDEO32: Descriptor 0B8000h, 0ffffh, 92h
LABEL_DATA32: Descriptor 0, SEG_DATA32_LEN-1, 92h
;GDT_48
gdt_len EQU $-LABEL_GDT
gdt_48 dw gdt_len-1
dd 0
;GDT选择子
code32 EQU LABEL_CODE32-LABEL_GDT
video32 EQU LABEL_VIDEO32 -LABEL_GDT
data32 EQU LABEL_DATA32 - LABEL_GDT
[SECTION .data1]
ALIGN 32
[BITS 32]
LABEL_SEG_DATA32:
BootMessage: db "hello",0
offsetBootMessage db BootMessage -$$
SEG_DATA32_LEN EQU $- LABEL_SEG_DATA32
[SECTION .s16]
[BITS 16]
start:
mov ax , cs
mov ds , ax
mov es , ax
mov ss , ax
mov sp , 0100h
;初始化代码段描述符
xor eax , eax
mov ax , cs
shl eax , 4
add eax , LABEL_SEG_CODE32
mov word [LABEL_CODE32+2] , ax
shr eax , 16
mov byte [LABEL_CODE32+4] , al
mov byte [LABEL_CODE32+7] , ah
;初始化数据段描述符
xor eax , eax
mov ax , ds
shl eax , 4
add eax , LABEL_SEG_DATA32
mov word [LABEL_DATA32+2] , ax
shr eax , 16
mov byte [LABEL_DATA32+4] , al
mov byte [LABEL_DATA32+7] , ah
;加载GDTR
xor eax , eax
mov ax , ds
shl eax , 4
add eax , LABEL_GDT
mov dword [gdt_48+2] , eax
lgdt [gdt_48]
;关中断
cli
;开A20地址线
in al, 92h
or al, 00000010b
out 92h, al
;置cr0的pe位
mov eax , cr0
or eax , 1
mov cr0 ,eax
;开中断
;sti
;jmp 进入保护模式
jmp dword code32:0
[SECTION .s32]
[BITS 32]
LABEL_SEG_CODE32:
mov ax , data32
mov ds , ax
mov ax , video32
mov gs , ax
mov ah , 0ch
xor esi , esi
xor edi , edi
mov esi , offsetBootMessage
mov edi , (80*10+0)*2
cld
sec:
lodsb
test al ,al
jz fir
mov [gs:edi] , ax
add edi , 2
jmp sec
fir:
jmp $
SEG_CODE32_LEN EQU $-LABEL_SEG_CODE32[/color][/color][/color]
第二个程序:
[color=008000]; ==========================================
; pmtest2.asm
; 编译方法:nasm pmtest2.asm -o pmtest2.com
; ==========================================
%include "pm.inc" ; 常量, 宏, 以及一些说明
org 0100h
jmp LABEL_BEGIN
[SECTION .gdt]
; GDT
; 段基址, 段界限 , 属性
LABEL_GDT: Descriptor 0, 0, 0 ; 空描述符
LABEL_DESC_CODE32: Descriptor 0, SegCode32Len - 1, DA_C + DA_32 ; 非一致代码段, 32
LABEL_DESC_DATA: Descriptor 0, DataLen - 1, DA_DRW ; Data
LABEL_DESC_VIDEO: Descriptor 0B8000h, 0ffffh, DA_DRW ; 显存首地址
; GDT 结束
GdtLen equ $ - LABEL_GDT ; GDT长度
GdtPtr dw GdtLen - 1 ; GDT界限
dd 0 ; GDT基地址
; GDT 选择子
SelectorCode32 equ LABEL_DESC_CODE32 - LABEL_GDT
SelectorData equ LABEL_DESC_DATA - LABEL_GDT
SelectorVideo equ LABEL_DESC_VIDEO - LABEL_GDT
; END of [SECTION .gdt]
[SECTION .data1] ; 数据段
ALIGN 32
[BITS 32]
LABEL_DATA:
;SPValueInRealMode dw 0
; 字符串
PMMessage: db "In Protect Mode now. ^-^", 0 ; 进入保护模式后显示此字符串
OffsetPMMessage equ PMMessage - $$
DataLen equ $ - LABEL_DATA
; END of [SECTION .data1]
[SECTION .s16]
[BITS 16]
LABEL_BEGIN:
mov ax, cs
mov ds, ax
mov es, ax
mov ss, ax
mov sp, 0100h
; 初始化 32 位代码段描述符
xor eax, eax
mov ax, cs
shl eax, 4
add eax, LABEL_SEG_CODE32
mov word [LABEL_DESC_CODE32 + 2], ax
shr eax, 16
mov byte [LABEL_DESC_CODE32 + 4], al
mov byte [LABEL_DESC_CODE32 + 7], ah
; 初始化数据段描述符
xor eax, eax
mov ax, ds
shl eax, 4
add eax, LABEL_DATA
mov word [LABEL_DESC_DATA + 2], ax
shr eax, 16
mov byte [LABEL_DESC_DATA + 4], al
mov byte [LABEL_DESC_DATA + 7], ah
; 为加载 GDTR 作准备
xor eax, eax
mov ax, ds
shl eax, 4
add eax, LABEL_GDT ; eax <- gdt 基地址
mov dword [GdtPtr + 2], eax ; [GdtPtr + 2] <- gdt 基地址
; 加载 GDTR
lgdt [GdtPtr]
; 关中断
cli
; 打开地址线A20
in al, 92h
or al, 00000010b
out 92h, al
; 准备切换到保护模式
mov eax, cr0
or eax, 1
mov cr0, eax
; 真正进入保护模式
jmp dword SelectorCode32:0 ; 执行这一句会把 SelectorCode32 装入 cs, 并跳转到 Code32Selector:0 处
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
[SECTION .s32]; 32 位代码段. 由实模式跳入.
[BITS 32]
LABEL_SEG_CODE32:
mov ax, SelectorData
mov ds, ax ; 数据段选择子
mov ax, SelectorVideo
mov gs, ax ; 视频段选择子
; 下面显示一个字符串
mov ah, 0Ch ; 0000: 黑底 1100: 红字
xor esi, esi
xor edi, edi
mov esi, OffsetPMMessage ; 源数据偏移
mov edi, (80 * 10 + 0) * 2 ; 目的数据偏移。屏幕第 10 行, 第 0 列。
cld ;清方向位
.1:
lodsb ;[si]->ax
test al, al
jz .2
mov [gs:edi], ax
add edi, 2
jmp .1
.2: ; 显示完毕
jmp $
SegCode32Len equ $ - LABEL_SEG_CODE32
; ------------------------------------------------------------------------[/color]
这两个程序 ,两个程序都用nasmw.exe编译通过,但是第一个程序在纯dos下运行,会出现一个 "处理器运到一个随机的错误", 第二个程序正常运行,在屏幕上出现 “In Protect Mode now. ^-^”.大家帮我找找两个程序的不同啊?