Orange'S初始化段寄存器

最近开始看《Orange‘S:一个操作系统的实现》,但因为不了解汇编,看第一个启动扇区的代码时就有疑惑:

1. 为了把cs中的值复制到ds和es中,首先需要将cs中的值复制到ax中,为什么不能直接复制?

2. mov ax, cs; mov ds, ax; mov es, ax;这三句初始化段寄存器的语句的意义是什么?

 1         org     07c00h
 2         mov     ax,     cs
 3         mov     ds,     ax
 4         mov     es,     ax
 5         call    DispStr
 6         jmp     $
 7 DispStr:
 8         mov     ax,     BootMessage
 9         mov     bp,     ax
10         mov     cx,     16
11         mov     ax,     01301h
12         mov     bx,     000ch
13         mov     dl,     0
14         int     10h
15         ret
16 BootMessage:    db      "Hello, OS World!"
17         times   510-($-$$)      db      0
18         dw      0xaa55

查了一些资料,对这两个问题有了一个基本的认识,但非常具体的细节因为不了解汇编还是不能解释。

对于问题1,intel x86架构就不允许mov的操作数为两个段寄存器,从nasm支持的操作中也找不到mov reg_sreg reg_sreg,至于为什么不支持,intel x86_64架构手册太繁杂了,就没找。

对于问题2,ds和es寄存器都是用来指示数据段位置的,所以在程序开始时,应该把它们初始化为正确的段地址,这样在程序中我们才可以正确地找到数据。但在小程序中,数据段和代码段一般都是同一个段,所以我们把cs中的值复制到ds和es中也就正确地初始化了ds和es。(所以基于此我猜测程序载入时cs会自动初始化为正确的代码段位置,下面对字符串的操作也应该会涉及到ds和es。找不到很明确的资料,反汇编boot.bin后下面的汇编我也不是很明白。)但是,这是在之前段寄存器还用来存储段位置的时候,现在在x86体系下,寄存器的位数已经足够寻址整个内存,所以段寄存器也就不再需要存储段位置。

我们可以在bochs中调试这段启动扇区代码,在x86_64的硬件架构上,cs,ds,es中的值始终是0。

es:0x0000, dh=0x00009300, dl=0x0000ffff, valid=1
    Data segment, base=0x00000000, limit=0x0000ffff, Read/Write, Accessed
cs:0x0000, dh=0x00009300, dl=0x0000ffff, valid=1
    Data segment, base=0x00000000, limit=0x0000ffff, Read/Write, Accessed
ss:0x0000, dh=0x00009300, dl=0x0000ffff, valid=7
    Data segment, base=0x00000000, limit=0x0000ffff, Read/Write, Accessed
ds:0x0000, dh=0x00009300, dl=0x0000ffff, valid=1
    Data segment, base=0x00000000, limit=0x0000ffff, Read/Write, Accessed
fs:0x0000, dh=0x00009300, dl=0x0000ffff, valid=1
    Data segment, base=0x00000000, limit=0x0000ffff, Read/Write, Accessed
gs:0x0000, dh=0x00009300, dl=0x0000ffff, valid=1
    Data segment, base=0x00000000, limit=0x0000ffff, Read/Write, Accessed

然后我们可以将初始化段寄存器的语句删除,重新编译后在虚拟机中运行,可以看到程序成功运行,初始化段寄存器语句的有无不影响程序在x86_64架构上的运行。

Orange'S初始化段寄存器

时间: 2024-11-05 12:25:42

Orange'S初始化段寄存器的相关文章

汇编-8086内部寄存器+对段寄存器使用的约定

<微型计算机原理与接口技术(第2版)>冯博琴 吴宁 主编-清华大学出版社——做笔记用 一.8088/8086的14个16位寄存器: //------------------------------------------------------------------------------------------------------------------------------- 1.通用寄存器——8个 (1)数据寄存器——4个 AX: 累加器,常用于存放算数逻辑运算中的操作数,另外所

CPU的段寄存器

http://www.cnblogs.com/tolimit/p/4775945.html?utm_source=tuicool&utm_medium=referral CPU的段寄存器 在CPU中,跟段有关的CPU寄存器一共有6个:cs,ss,ds,es,fs,gs,它们保存的是段选择符.而同时这六个寄存器每个都有一个对应的非编程寄存器,它们对应的非编程寄存器中保存的是段描述符.系统可以把同一个寄存器用于不同的目的,方法是先将其寄存器中的值保存到内存中,之后恢复.而在系统中最主要的是cs,ds

栈Stack和段寄存器SS,SP(学习汇编)

1. 栈有2个基本操作:入栈.出栈 2. 栈顶的元素总是最后入栈,最先出栈:后进先出. 3. 8086CPU提供入栈和出栈的指令,最基本的两个是 PUSH(入栈) 和 POP(出栈) push ax 表示将AX寄存器的内容送入栈中, pop ax 表示从栈顶取出数据送入AX寄存器中.     8086CPU的入栈和出栈操作都是以字(word)为单位的. 4. 8086CPU中,段寄存器SS:存放栈顶段地址,段寄存器SP: 存放栈顶的偏移地址. 5. 任意时刻:SS:SP 指向栈顶元素. 6. 8

段寄存器和8种地址寻址方式

段寄存器是因为对内存的分段管理而设置的. 16位CPU有四个段寄存器,其程序可同时访问四个不同含义的段,引用方面有如下规定:1. 取命令:段寄存器CS指向存放程序的内存段,IP是用来存放下条待执行的指令在该段的偏移量,把它们合在一起可在该内存段内取到下次要执行的指令.2. 取堆栈:段寄存器SS指向用于堆栈的内存段,SP是用来指向该堆栈的栈顶,把它们合在一起可访问栈顶单元.另外,当偏移量用到了指针寄存器BP,则其缺省的段寄存器也是SS,并且用BP可访问整个堆栈,不仅仅是只访问栈顶.3. 取数据:段

汇编之FS段寄存器

FS寄存器指向当前活动线程的TEB结构(线程结构) 偏移  说明 000  指向SEH链指针 004  线程堆栈顶部 008  线程堆栈底部 00C  SubSystemTib 010  FiberData 014  ArbitraryUserPointer 018  FS段寄存器在内存中的镜像地址 020  进程PID 024  线程ID 02C  指向线程局部存储指针 030  PEB结构地址(进程结构) 034  上个错误号 得到KERNEL32.DLL基址的方法 assume fs:no

02段寄存器

段寄存器: 在使用汇编写某个地址时:mov dword ptr ds:[0x123456],eax 其实我们真正读写的地址是:ds.base + 0x123456 而段寄存器共有八个 分别为: ES CS SS DS FS GS LDTR TR 2.段寄存器的结构. 段寄存器共96位 其中80位不可见,16位可见 //图形表示: 结构体表示: struct SegVent { WORD Selector;    //16位Selector //段选择子 WORD Attributes;    /

汇编——段寄存器

段寄存器 8086CPU有14个寄存器 AX,BX,CX,DX,si,di,sp,bp,ip,cs,ss,ds,es,psw 其中有8个通用寄存器 8086寄存器16位,可以存放两个字节 AX BX CX DX一般用来存放一般数据 为保证兼容性,这四个寄存器可以分为两个独立的8位寄存器使用 AX可以分为AH和AL H高L低 同样的对于ABCD-X 字在寄存器中的存储 一个字可以存在一个16位寄存器中 Word=2B 关于数制的讨论 二进制太冗长 几条汇编指令 Mov ax,18         

段寄存器(8086CPU)和代码段

1.段寄存器 8086CPU有4个段寄存器:CS.DS.SS.ES.当8086CPU访问内存时,由这4个段寄存器提供内存单元的段地址. CS和IP是8086中最关键的寄存器,他们指示了CPU当前要读取指令的地址.CS是代码段寄存器,IP为指令指针寄存器.在8086PC机中,任意时刻,设CS中的内容是M,IP中的内容是N,8086CPU将从内存地址:M*16+N处读取指令并执行.也可以这样表述,8086机中,任意时候,CPU将CS:IP指向的内容当做指令执行,.CPU将CS.IP中的内容当做指令的

汇编语言——寄存器(内存访问 ds数据段寄存器,ss栈段寄存器)

在内存中字的存储 这段话的主要意思是:一个字=2B=16bit,CPU中是用两个内存单元储存一个字(假如获取0地址存放的字型数据,就是获取它的高位字节0+1位和低位字节0位的数据,数据由高地址位向低地址位读) 问题: (1)0地址单元中存放的字节型数据是多少? #  20H(2)0地址字单元中存放的字型数据是多少? # 4e20H(3)2地址字单元中存放的字节型数据是多少? # 12H(4)2地址单元中存放的字型数据是多少?    #  0012H(5)1地址字单元中存放的字型数据是多少? #