读过《自己动手写操作系统》请进 一个汇编问题 (没读过也可以进,反正是汇编方面的问题)
时间:2008-02-13
来源:互联网
jmp SELECTOR_KERNEL_CS:csinit
csinit: ; “这个跳转指令强制使用刚刚初始化的结构”——<<OS:D&I 2nd>> P90.
选择子指定的段是0~4G的一个段
为什么是jmp xxx:csinit 而不是jmp xxx:文件开始的物理地址+csinit
因为csinit是相对于文件开头的偏移 不是相对于内存的
在loader.asm中跳转进保护模式就写成了jmp dword SelectorC:(BaseOfLoaderPhyAddr+LABEL_PM_START) 是物理地址加偏移 这才应该是对的啊
但是运行时,2个地方都没出现异常,用bochs调试 发现jmp xxx:csinit 的确jmp到了csinit标签 而不是相对于0x00偏移csinit的地方
这是为什么?
作者: sm_zl_kimi 发布时间: 2008-02-13
转短跳的参数是相对偏移,不管代码加载到什么地方,相对偏移都是不变的
绝对转跳就不用说了。
作者: jennyvenus 发布时间: 2008-02-13
http://code-search.kingofcoder.com/searchCode2.php
作者: kockoc2 发布时间: 2008-02-13
作者: jennyvenus 发布时间: 2008-02-13
Assembly code
LABEL_LOADING_FILE: push ax push bx mov ah,0eh mov al,'.' mov bl,0fh int 10h pop bx pop ax mov cl,1 call ReadSector xor eax,eax mov ax,[wFatNo] call GetFATEntry cmp ax,0fffh jz LABEL_LOAD_OVER mov word [wFatNo],ax add ax,RootDirSectors add ax,DeltaSectorNo add bx,[BPB_BytsPerSec] mov cx,BaseOfKernelFile mov es,cx jmp LABEL_LOADING_FILE
这里的LABEL_LOADING_FILE 没必要再加个loader的地址了吧,同样 jmp xxx:csinit 同样是跳到一个节里,也没必要加loader的绝对地址了
我也不肯定 期望和楼主探讨下
作者: littlehedgehog 发布时间: 2008-03-18
作者: guoxyj 发布时间: 2008-03-19
作者: ypyf3000 发布时间: 2008-03-20
作者: UltraBejing 发布时间: 2008-05-01
在保护模式下,这里的SELECTOR_KERNEL_CS应该是个选择子吧,但是为什么SELECTOR_KERNEL_CS定义成下面的样子:
SELECTOR_KERNEL_CS equ 8
这个是怎么引用到刚刚初始化了的选择子的阿?
问题还没解决,这个贴不能就这么沉了呀!
顶!
作者: w5543081 发布时间: 2008-11-28
jmp dword 0x08:0xXXXXXXXX
自动把这个selector放到cs寄存器上...
另外,不明白你"为什么SELECTOR_KERNEL_CS定义成下面的样子: SELECTOR_KERNEL_CS equ 8"
是有什么问题?你认为是应该怎么样呢?
希望我的回复能够帮助你 [:-)
作者: harry_1523 发布时间: 2008-11-28
long或更远时才会是绝对地址跳转
而相对的base都是当前PC ,考虑PC是在文件头?
作者: xiaopoy 发布时间: 2008-11-28
------------------------------------
jmp dword 0x08:0xXXXXXXXX
自动把这个selector放到cs寄存器上...
------------------------------------
jmp dword 0x08:0xXXXXXXXX中0xXXXXXXXX是offset吧,
那么你说的selector 是那个selector呢?
给你看一下源代码吧:
============================================
SELECTOR_KERNEL_CS equ 8 ; 下面jump用到的参数
; 导入函数
extern cstart
extern exception_handler
extern spurious_irq
; 导入全局变量
extern gdt_ptr
extern idt_ptr
extern disp_pos
bits 32
[SECTION .bss]
StackSpace resb 2 * 1024
StackTop: ; 栈顶
[section .text] ; 代码在此
global _start ; 导出 _start
_start:
mov esp, StackTop ; 堆栈在 bss 段中
mov dword [disp_pos], 0
sgdt [gdt_ptr] ; 取得原来GDT的内容,cstart() 中将会用到 gdt_ptr
call cstart ; 在此函数中改变了gdt_ptr,让它指向新的GDT
lgdt [gdt_ptr] ; 使用新的GDT(与原来的GDT一样,只是存储地方不同),加载
lidt [idt_ptr]
jmp SELECTOR_KERNEL_CS:csinit
csinit: ; “这个跳转指令强制使用刚刚初始化的结构”——<<OS:D&I 2nd>> P90.<--不知道书里写
;的么,还没有找到这本书。
;jmp 0x40:0
;ud2
sti
hlt
==================================================================================
以下是选择子的定义:
; GDT ------------------------------------------------------------------------------------------------------------------------------------------------------------
; 段基址 段界限 , 属性
LABEL_GDT: Descriptor 0, 0, 0 ; 空描述符
LABEL_DESC_FLAT_C: Descriptor 0, 0fffffh, DA_CR | DA_32 | DA_LIMIT_4K ; 0 ~ 4G
LABEL_DESC_FLAT_RW: Descriptor 0, 0fffffh, DA_DRW | DA_32 | DA_LIMIT_4K ; 0 ~ 4G
LABEL_DESC_VIDEO: Descriptor 0B8000h, 0ffffh, DA_DRW | DA_DPL3 ; 显存首地址;
GDT ------------------------------------------------------------------------------------------------------------------------------------------------------------
GdtLen equ $ - LABEL_GDT
GdtPtr dw GdtLen - 1 ; 段界限
dd BaseOfLoaderPhyAddr + LABEL_GDT ; 基地址
; GDT 选择子 ----------------------------------------------------------------------------------
SelectorFlatC equ LABEL_DESC_FLAT_C - LABEL_GDT
SelectorFlatRW equ LABEL_DESC_FLAT_RW - LABEL_GDT
SelectorVideo equ LABEL_DESC_VIDEO - LABEL_GDT + SA_RPL3
; GDT 选择子 ----------------------------------------------------------------------------------
============================================
如上面所示,上面的选择子有3个,你说的自动选择selector 是选择哪个selector 啊?
接着顶!顶!顶!
作者: w5543081 发布时间: 2008-11-29
作者: beijingbeerman 发布时间: 2008-12-02
如下代码:
-------------------------------
jmp SELECTOR_KERNEL_CS:csinit
-------------------------------
SELECTOR_KERNEL_CS是已经在loader.asm中计算出来的0x08,第一个选择子的相对地址。
而此段代码的编译格式是elf格式文件,里面的csinit是绝对地址,
所以面的jmp会直接跳到此段的csinit 处。
以上的解释是否正确,请大虾批评。
作者: w5543081 发布时间: 2008-12-03
学习
作者: xtdumpling 发布时间: 2008-12-03
作者: YX799808850 发布时间: 2008-12-03
作者: beijingbeerman 发布时间: 2008-12-04
“为什么是jmp xxx:csinit 而不是jmp xxx:文件开始的物理地址+csinit ” 这个问题是因为内核在编译的时候就以经加了个一个偏移了,那个偏移就是内核相对内存物理地址0的偏移了,所以不用像在LOADER里一样处理。而是直接JMP到csinit这个LABLE上。
作者: zhizhi_2008 发布时间: 2008-12-05
作者: areful 发布时间: 2008-12-06
作者: w5543081 发布时间: 2008-12-08
作者: filec75 发布时间: 2008-12-08
作者: qap22 发布时间: 2008-12-08
作者: huanghengpp 发布时间: 2009-02-17
作者: caojapan 发布时间: 2009-05-12
nasm -f elf -o kernel.o kernel.asm
ld -s Ttext 0x30400 -o kernel.bin kernel.o
所以kernel.bin 文件内部的指令地址 = 指令相对文件头的相对位移 + 0x30400
因此jmp selector_kernel : csinit 就是 jmp selector_kernel_cs : csinit+0x30400
另外 selector_kernel_cs = 8 是因为 Selectorflatc=8 即 cs=8 它指向拷贝到kernel空间的描述符
LABEL_DESC_FLAT_C
清楚了吧
作者: cailong1988 发布时间: 2010-11-16
热门阅读
-
office 2019专业增强版最新2021版激活秘钥/序列号/激活码推荐 附激活工具
阅读:74
-
如何安装mysql8.0
阅读:31
-
Word快速设置标题样式步骤详解
阅读:28
-
20+道必知必会的Vue面试题(附答案解析)
阅读:37
-
HTML如何制作表单
阅读:22
-
百词斩可以改天数吗?当然可以,4个步骤轻松修改天数!
阅读:31
-
ET文件格式和XLS格式文件之间如何转化?
阅读:24
-
react和vue的区别及优缺点是什么
阅读:121
-
支付宝人脸识别如何关闭?
阅读:21
-
腾讯微云怎么修改照片或视频备份路径?
阅读:28