当裸机没有org 0x7c00之后 ????
个人的认为是ORG是指示各种变量名的偏移量,下面是这段代码如果如何使用ORG这个指令就可以正常的在虚拟机上执行,如果没有的话,那么无法正常地跳入保护模式。。。我认为这与变量名的偏移量错误有关,但不知道错在哪里,希望哪位可以帮帮忙,非常感谢!
; 没有定义USRORG,所以这小段代码没有编译
%ifdef USEORG
org 0x7c00
%endif
jmp begin_real_mode
setupmsg: db "Loading setup block new... "
SETUPMSGLEN equ $-setupmsg
[BITS 16]
begin_real_mode:
mov ax,cs
mov ds,ax
mov es,ax
; 代码最开始的时候,IP为0X7C00,CS为0X0000
; 现在把它们的值替换过来,这小段代码相当于as86汇编中的 jmpi flag:#0x7c0
%ifndef USEORG
db 0xea
dw flag
dw 0x7c0
flag:
mov ax,cs
mov ds,ax
mov es,ax
%endif
; 设置保护模式的代码段描述符和数据段描述符
mov word [codebase],ax
mov word [database],ax
; 打印消息
mov ax,0x1301
mov bp,setupmsg
mov cx,SETUPMSGLEN
mov dx,0
mov bx,12
int 0x10
cli
lgdt [ gdtr ]
mov eax,cr0
or al,0x01
mov cr0,eax
jmp codesel:begin_proected_mode
[BITS 32]
begin_proected_mode:
; 在屏幕上打印一个绿色的字符A
mov ax,videosel
mov gs,ax
mov word [gs:110],0x0A41
jmp $
; 下面是为了保护模式而设置的描述项
[BITS 16]
gdtr:
dw gdt_end - gdt - 1
dd gdt
gdt:
nullsel equ $-gdt
dd 0,0
codesel equ $-gdt
dw 0x0ffff ; 4G
codebase:
dw 0x0
db 0x00
dw 0xcf9a
db 0x00
datasel equ $-gdt
dw 0x0ffff ; 4G
database:
dw 0x0
db 0x00
dw 0xcf92
db 0x00
videosel equ $-gdt
dw 3999 ; 80 cols * 25 * rows * 2bytes - 1
dw 0x8000
db 0x0b
dw 0x0092
db 0x00
gdt_end:
times 510-($-$$) db 0
dw 0xAA55
这段代码我是在Ubuntu 的 virtualbox上运行的
编译方式(终端)是:nasm setup.asm -o os.img
setup.asm 就是这段代码的文件名
[解决办法]
由于引导内容是被载入到 7c00h 处的,所以,如果不加 org 7c00h 语句的话,缺省的就被认为是加载在 0000 处,这样,对变量的引用全部错误。因为对变量的引用指令里,变量是以完整地址形式存在的,无论程序载入在哪里,所引用的地址都是不变的,不会因为载入在 7c00h 处时对 7de0h 处的引用在载入地址改变到 0000 处时随之变为 01e0h 而仍然是 7de0h;这和普通的(条件)转移指令不同(这类指令是以目标相对偏移形式存在的,代码整体移动,相互间的偏移不会变化,所以转移不会出错,当然了,部分绝对转移指令或目标地址直接引用的间接转移类指令除外)。
[解决办法]
"那么标号的偏移将从0X7COO开始计起" 有什么问题呢?
进入保护模式了,应该也把段变成32位的了
多弄一个段
[解决办法]
偏移量 是相对偏移的啦,不是绝对地址。。。