- 博客(15)
- 收藏
- 关注
原创 从二进制的角度看类(Class)
大三时选了C++的课程,老师强调:相对于C语言来说,C++最核心的改动在于引入了类的概念。现在为止,我只用C++写过一些简单的程序,包括使用MFC,并没有使用过诸如模板的高级C++特性。围绕类,一直有两个问题悬在心中: 1. 为什么要引入类? 2. 类的二进制本质究竟是什么?最近,我探究了第二个问题,看到一些有意思的结论,简单总结在这儿。使用的操作系统是Ubuntu 14.
2015-02-04 17:27:34 391
原创 静态链接,静态链接库,CRT
这里只讨论静态链接库。 库是编译好的目标代码的集合。程序员可以在库中按需取用,将自己需要的代码链接入自己的程序。linux下,编译好的.o目标文件用ar(archive)打包,形成.a(archive)文件。类似的,Windows下有.lib文件。一个典型的.a文件是/usr/lib/i386-linux-gnu/libc.a。该文件以每个函数一个.o文件的形式给出了很多实现,比如b
2015-02-04 17:23:33 1338
原创 从静态链接的角度看global、static与声明
就像搭积木,链接将不同的软件模块组装成一个完整的可运行的程序。对于连接器来说,软件模块的基本单位是目标文件,来自于某个源文件。a.c要想引用一个外部的函数或者变量,只需进行相应的声明就可以。目标文件以段(section)为单位将程序组织起来。链接大体上可以分为两步: 1. 同名段合并。典型的合并就是两个.text段(代码段)的合并。 2. 符号重定位。符号是个很宽泛的概念,目标
2015-02-04 17:22:53 997
原创 装载(load)
所谓装载(load),指将一个程序从硬盘搬移到RAM,跳转过去执行的过程。如果不考虑动态链接的话,装载过程并不复杂。这篇文档的作用,就是阐明Linux和Windows究竟是如何将一个程序装载到内存中的。 在Linux下,可执行文件的保存格式是ELF(Executable Linkable Format),而Windows下的可执行文件为PE(Portable Executable)。EL
2015-02-04 17:22:18 1668
原创 一张全景图——保护模式下的“任务”(Task)
最近读了《x86汇编语言——从实模式到保护模式》一书的第二部分:保护模式。了解了关于保护模式的皮毛知识。画了一张图,帮助理解所谓“任务”。下图展示了一个运行中的任务,包括LDTR、TR、GDTR等寄存器,IDT、TSS、GDT、目录表、页表等数据结构,线性地址和物理地址之间的映射,以及这些寄存器和数据结构之间的关系。 草草一张图,顿感保护模式之复杂,又叹保护模式之简单。
2014-12-21 10:58:49 650 1
原创 TLB与《x86汇编语言——从实模式到保护模式》的一个疑似错误
TLB(Translation Lookaside Buffer)是CPU内部的一个高速缓存,用于最近经常使用的缓存线性地址和物理地址的映射关系。TLB的存在会为程序的编写带来容易忽略的错误。当内存中的目录和页表发生变化时,这些变化并不会立即反映在TLB中。此时,CPU依然依靠TLB完成线性地址到物理地址的映射。所以,一个可靠的方式是更改目录和页表后,将cr3的内容取出,然后重新填入cr3。CR3
2014-12-21 10:57:12 852
原创 实模式和保护模式中断机制的简单对比与一点硬件细节
和实模式相比,保护模式下的中断处理有两点最大的区别。首先,中断向量表可以在内存中自由浮动。其次,中断的功能获得了拓展。 在实模式下,中断向量表占据内存最低的1KB,共256个表项。每个表项4子节,包含一个2子节的段地址和2子节的偏移,即中断处理程序的入口地址。但是在保护模式下,中断向量表可以在内存中自由浮动。就像GDT被GDTR指向一样,中断向量表被IDTR(Interrupt Desc
2014-12-21 10:55:43 3290
原创 TSS----任务切换的核心
任务切换的核心在于TSS。 TSS(Task State Segment)是一个任务存在的标志。一个任务可以没有自己的LDT,但是一定要有TSS。保护模式下的处理器的一个设计目标就是支持多任务。TSS是为了达到此目标而引入的最重要的数据结构。TSS和任务唯一对应,保存有任务运行状态相关的所有必要信息。任何时候,只要获知一个任务的TSS,就相当于获知了该任务现在运行在了什么地方,所有寄
2014-12-21 10:53:30 2167
原创 保护模式下的特权级检查
CPU通过GDT保护了内存区域。通过GDT,不同的内存区域被规定了大小,赋予了访问权限,比如是否可写,是否可运行。但是对于支撑多任务来说,这还远远不够。譬如我们无法做到让某个数据段尽可被操作系统访问,不可被其它应用程序访问。特权级引入了更强力的任务保护。 特权级的想法是将不同的特权给予不同的任务。所谓特权,指访问资源的能力。比如操作系统需要访问所有可以访问的资源,而某个应用程序只需要有权
2014-12-21 10:52:12 635
原创 笔记----从MBR到OS到application
一个OS_core: 这个工程包含三段代码,一是引导代码,负责引导OS,二是OS,负责引导app,三是app。最后,OS会在app返回之后hlt。 下面阐述每段代码的结构。 1. 引导代码: 1) 流程:进入保护模式-->从硬盘中将OS代码读入内存-->为OS将要使用的段"注册"段描述符-->跳转到OS 2) 子程序:
2014-11-11 21:21:39 427
原创 386对存储器的保护与栈段初始化
386对存储器的保护与栈段初始化 1. 更换段寄存器时要注意段选择子不能指向GDT以外的位置 2. 更换段选择器时要注意段的属性要和段寄存器相符,比如数据段不得由CS指向,SS只能指向数据段,且该数据段必须可写。 3. 每利用"偏移地址寄存器"进行寻址时,比如BX,IP,SS,CPU都会检测偏移地址是否超出该段得合法地址范围,如果超出,会引发中断。至于段的合法地址如何
2014-11-11 21:20:41 474
原创 如何进入保护模式
如何进入保护模式 这是个复杂的过程,其原因在于保护模式本身是复杂的。 相对于8086来说,386增加了很多新寄存器,用于支持多任务操作系统,或者说让CPU能工作在保护模式下。CR0就是其中之一。CR指Control Register,控制寄存器。CR0是CR中的一个。CR的最后一个bit是PE位,Protected-mode Enable,保护模式使能位。386开机后工作在实模
2014-11-11 21:19:28 1661
原创 IA-32
IA-32指Intel Architecture-32bit,也就是从8086发展而来的32位处理器结构。IA-32的指令格式沿用了16位8086的格式,在其基础上做了向32位的拓展: 前缀|操作码|寻址方式和操作数类型|立即数|偏移量其中,前缀是可选的,且可以有多个。前缀有重复前缀,比如REP,段超越前缀,比如ES:等等;操作码就是真正的instruction,比如ad
2014-11-11 21:18:30 802
原创 8086汇编杂记
8086CPU拥有20位宽的地址总线,可以达到1MB的寻址空间,但是寄存器都是16bit的,那么如何进行寻址呢?方法是分段。一个20位的地址被分成两部分:16bit+4bit,分别保存在所谓段(segment)寄存器和普通寄存器(或者立即数)中。当访问外部地址时,段地址和偏移地址将被硬件转转换成物理地址,从地址总线输出。从运算上来看,物理地址 = 段地址 * 16 + 偏移地址。因为16bit左移
2014-10-26 17:58:28 582
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人