您的位置 首页 java

Java,CPU、汇编语言、内存管理、文件系统、操作系统启动

CPU的架构和概念

1、CPU、CPU指令集、X86架构、ARM架构

CPU,(Central Processing Unit),计算机系统的运算和控制核心,是信息处理、程序运行的最终执行单元。

指令,指挥计算机系统工作的指示和命令;指令集,CPU用来计算和控制计算机系统的一套指令的集合,包含:复杂指令集运算(Complex Instruction Set Computing,CISC)和精简指令集运算(Reduced Instruction Set Computing,RISC);

x86,基于Intel 8086且向后兼容的中央处理器指令;IA32,Intel Architecture 32bit,英特尔32位体系架构,通常也被称为i386、x86-32、x86等;IA64,Intel和惠普联合推出的64位体系架构,不兼容原有的32位;AMD64,AMD推出了兼容32位的64位指令集,基于IA-32的扩展,Intel后来也采用该架构,称为x86-64或者x64。

ARM架构,高级精简指令集机器(Advanced RISC Machine),属于32位精简指令集(RISC)处理器架构,而x86架构采用CISC; Android系统主要应用于ARM,但不仅限于ARM,通过编译控制,在x86、MAC等体系结构的机器上同样可以运行。

2、CPU的总线(Bus)

总线,计算机各种功能部件之间传送信息的公共通信干线,它是由导线组成的传输线束;是一种内部结构,它是cpu、内存、输入、输出设备传递信息的公用通道,主机的各个部件通过总线相连接,外部设备通过相应的接口电路再与总线相连接,形成了计算机硬件系统。

数据总线,CPU与存储器、I/O接口设备之间传送数据信息(指令数据信息)的总线,是双向传输。

地址总线,CPU向存储器、I/O接口设备发出的地址信息,地址总线上传送的地址信息仅由CPU发出,是单向传输的;它决定了CPU访问内存的寻址能力和寻址范围,也就是支持内存的大小,如:20根总线;2的20次方,支持1MB内存。

控制总线,传送控制信号,实现对外部器件进行控制,由CPU至存储器、I/O接口设备的控制信号,有I/O接口送向CPU的应答信号、请求信号,是双向传输。控制信号包括时序信号、状态信号和命令信号(如读写信号、忙信号、中断信号)等。

3、CPU的内部结构

CPU和内存是由许多晶体管组成的电子部件,通常称为IC(Integrated Circuit,集成电路);功能方面,CPU的内部由寄存器,控制器,运算器和时钟四部分构成,各部分之间由电流信号相互连通。

寄存器,可用来暂存指令,数据等处理对象,可以将其看做是内存的一种,是高速缓存;根据种类的不同,一个CPU内部会有20~100个寄存器。

控制器,负责把内存上的指令,数据等读入寄存器,并根据指令的执行结果来控制整个计算机。

运算器,负责运算从内存读入寄存器的数据。

时钟,负责发出CPU开始计时的时钟信号;也有些计算机的时钟位于CPU的外部。

4、CPU的寄存器

CPU是寄存器的集合体,程序是把寄存器作为对象来描述的;使用高级语言编写的程序会在编译后转化成机器语言,然后通过CPU内部的寄存器来处理。不同类型的CPU,其内部寄存器的数量,种类以及寄存器存储的数值范围都是不同的;根据功能的不同,可以将寄存器大致划分为八类。

累加寄存器:存储执行运算的数据和运算后的数据;标志寄存器:存储运算处理后的CPU的状态;程序计数器(PC):存储下一条指令所在内存的地址;基址寄存器:存储数据内存的起始地址;变址寄存器:存储基址寄存器的相对地址;通用寄存器:存储任意数据;指令寄存器:存储指令,CPU内部使用,程序员无法通过程序对该寄存器进行读写操作;栈寄存器:存储栈区域的起始地址;其中,程序计数器,累加寄存器,标志寄存器,指令寄存器和栈寄存器都只有一个,其他的寄存器一般有多个。

5、8086 CPU的14个寄存器

8个通用寄存器:4个数据寄存器,AX<Accumlator X>,累加寄存器;BX<Base X>,基址寄存器;CX<Counter X>,计数寄存器;DX<Data X>,数据寄存器。2个指针寄存器P,SP<Stack Poiner>,栈顶指针寄存器;BP<Base Poiner>,基址指针寄存器。2个変址寄存器I,SI<Source Index>,源変址寄存器;DI<Destination Index>,目的変址寄存器。

2个控制寄存器:IP<Instruction Pointer>,指令指针寄存器;flags,标志寄存器。

4个段寄存器:CS<Code Segment>,代码段寄存器;DS<Data Segment>,数据段寄存器;ES<Extra Segment>,附加数据段寄存器;SS<Stack Segment>,栈段寄存器。

CPU的运行模式

1、实模式(16位)

Intel CPU有三种运行模式:实模式、保护模式和虚拟实模式。

Intel的8086到80186处理器都只有一种运行模式,就是实模式,这个模式下,CPU用20根地址线进行内存寻址,所以在这个模式下CPU只能访问从00000h->FFFFFh的地址范围的内存,即1MB大小的内存。同时使用16根数据线,使用16位内部寄存器运行16位指令。为了能够支持使用20位的地址来访问1MB的内存,于是就对内存的使用引入了分段机制,CPU设置了4个16位的段寄存器:CS、DS、ES、SS,应对地址总线的高16位,寻址时,将段寄存器中的值向左移4位在加上段内偏移量就得到了物理地址,这样就实现了16位内存地址到20位物理地址的转换,这种方式叫做“映射”。由于其偏移量只能用16位来表示,所以其支持的段的大小只有64K字节。

在实模式下,系统一次只能运行一个程序,其他程序都处于休眠状态。在这个模式下,任何一个程序都可以访问内存的任何地方,并没有一种保护机制来防止一个程序被另一个程序重写,即便是对于在内存中的操作系统也是如此。所以如果有几个程序存在内存中,很可能会因为其中的一个程序修改了另一个程序的数据而导致系统崩溃。

为了能够和前面的CPU兼容,80286及以后的x86系列的处理器仍然是开机启动时工作在是实模式下,这时的CPU和8086没有任何区别,只是运行速度比8086更快而已,然后通过操作系统设置之后,就可以进入一个更加先进的模式,即保护模式。

2、虚拟8086模式

虚拟8086模式,在当初设计Intel 80386 CPU的时候,需要解决的一个难题是如何让运行在16位模式下的程序能够在80386的保护模式中运行。为此Intel的设计人员在80386中加入了虚拟8086模式。

在虚拟8086模式中,CPU把内存分为许多大小为1M的部分,每个部分分配给一个任务。大部分16位模式下的程序能够不经任何修改就运行在该模式下,每个程序都有属于他们的1M内存。

3、保护模式(32位)

保护模式,要发挥80386及x86系列处理器的全部优势,就要在保护模式下。 保护模式采用的是32根地址总线和数据总线,运行32位指令,可寻址高达4G(2的32次方)字节的物理地址空间,实模式下只能寻址1M字节的物理地址空间。

在实模式下,系统一次只能运行一个程序,其他程序都处于休眠状态。在这个模式下,任何一个程序都可以访问内存的任何地方,并没有一种保护机制来防止一个程序被另一个程序重写,即便是对于在内存中的操作系统也是如此。所以如果有几个程序存在内存中,很可能会因为其中的一个程序修改了另一个程序的数据而导致系统崩溃。

为了能够和前面的CPU兼容,80286及以后的x86系列的处理器仍然是开机启动时工作在是实模式下,这时的CPU和8086没有任何区别,只是运行速度比8086更快而已,然后通过操作系统设置之后,就可以进入一个更加先进的模式,即保护模式。

保护模式采用了虚拟内存,并采用分段和分页技术相结合的方式,其支持的最大的段的大小也从实模式的64K增长到4G。同时保护模式的地址转换方式也发生了变化。此时段寄存器里存的不在是基址,而是段选择子。通过段选择子来选出段的描述符,描述符用来描述一个段,包含了段基址、段界限、段属性等段的信息。得到段基址之后,再加上偏移量就得到了线性地址,与实模式最大的区别是保护模式的基址不要偏移。得到线性地址之后,如果禁止分页线性地址就被解释为物理地址;如果允许分页线性地址就通过页表映射到物理地址。

4、64位操作模式(64位)

Intel 64架构引入了一个新模式,称为 IA-32e。从技术上看,这个模式包含两个子模式:兼容模式(compatibility mode)和 64位模式(64-bit mode)。不过它们常常被看做是模式而不是子模式。

在兼容模式下,现有的16位与32位应用程序通常不用进行重新编译就可以运行。但是,16位Windows(Win16)和DOS应用程序不能运行在64位 Microsoft Windows下。与早期Windows版本不同,64位Windows没有虚拟DOS机器子系统来利用处理器的功能切换到虚拟8086模式。

在64位模式下,处理器执行的是使用64位线性地址空间的应用程序。这是64位 Microsoft Windows的原生模式,该模式能使用64位指令操作数。

汇编语言

1、汇编语言概述

汇编器(assembler)是一种工具程序,用于将汇编语言源程序转换为机器语言。链接器(linker)也是一种工具程序,它把汇编器生成的单个文件组合为一个可执行程序。还有一个相关的工具,称为调试器(debugger),使程序员可以在程序运行时,单步执行程序并检查寄存器和内存状态。

保留字(reserved words)有特殊意义并且只能在其正确的上下文中使用。默认情况下,保留字是没有大小写之分的。比如,MOV与mov、Mov是相同的。标识符(identifier)是由程序员选择的名称,它用于标识变量、常数、子程序和代码标签。伪指令 (directive) 是嵌入源代码中的命令,由汇编器识别和执行。伪指令不在运行时执行,但是它们可以定义变量、宏和子程序;为内存段分配名称,执行许多其他与汇编器相关的日常任务。指令(instruction)是一种语句,它在程序汇编编译时变得可执行。汇编器将指令翻译为机器语言字节,并且在运行时由 CPU 加载和执行。

语法:略;使用举例,将数字5送入eax寄存器:mov eax, 5

2、汇编编译器和编译执行流程

NASM,全称The Netwide Assembler,是一款基于80×86和x86-64平台的汇编语言编译程序,其设计初衷是为了实现编译器程序跨平台和模块化的特性。NASM支持大量的文件格式,包括Linux,*BSD,a.out,ELF,COFF,Mach−O,Microsoft 16−bit OBJ,Win32以及Win64,同时也支持简单的二进制文件生成。它的语法被设计的简单易懂,相较Intel的语法更为简单,支持目前已知的所有x86架构之上的扩展语法,同时也拥有对宏命令的良好支持。MASM,宏汇编程序是具有宏加工功能的汇编程序,可以用它定义含参数的程序段,在使用的位置上调用它们,汇编时将进行宏(指令)展开,把宏定义所预先定义的指令目标代码插在该位置上。TASM,Borland公司开发的汇编编译器,被广泛用于Turbo C,Quick Basic等编译器,用作中间过渡编译,它也能独立的编译纯汇编或是Win32Asm的代码。具有编译快速,高效的特点,至今依然是汇编开发的首选利器。GAS,指代GUN ASM,在 Linux 源代码中,以.S(或.s)为扩展名的文件是包含汇编语言代码的文件。

汇编编译流程: 源文件(.asm)-> 汇编器 -> 目标文件(可以C和C++目标文件兼容) -> 链接器<包含链接库> -> 可执行文件(纯二进制,exe格式、ELF格式等) -> CPU执行 -> 输入 -> 输出

CPU访问内存和寻址

1、内存管理

内存(Memory),随机存取存储器,RAM(Random Access Memory);内存与CPU进行沟通的桥梁,程序运行时数据大部分保存在内存中。

Intel从80386开始,有32位地址总线,进入了32位的时代。在Real Mode(16-bit系统)下内存地址的访问:Segment:Offset,Segment是一个段的Base Address(基地址),最大长度是64 KB(2的16次方字节),Offset则是相对于此Segment Base Address的偏移量,寻址方式为:物理地址=段基址x16+段内偏移地址。

到了Protected Mode(32-bit系统),内存的管理模式分为两种:段模式和页模式,其中页模式也是基于段模式,也就是说内存管理模式是:纯段模式和段页式,实际上就是段模式是必不可少的,而页模式则是可选的,如果使用页模式,则是段页式;否则这是纯段模式。

在Protected Mode运行在32-bit系统上,一个段的描述则包括3方面因素:[Base Address, Limit, Access],它们加在一起被放在一个64-bit长的数据结构中,被称为段描述符。Intel为了保持向后兼容,将段寄存器仍然规定为16-bit,而把这些长度为64-bit的段描述符,放入一个数组中,而将段寄存器中的值作为下标索引来间接引用(实际上是将段寄存器中的高13-bit的内容作为索引),这个全局的数组就是GDT, Global Descriptor Table,即全局描述符表。

GDT是可以被放在内存的任何位置,当通过段寄存器来引用一个段描述符时,CPU必须知道GDT的入口,也就是基地址放在哪里,所以Intel的设计者门提供了一个寄存器GDTR用来存放GDT的入口地址,程序员将GDT设定在内存中某个位置之后,可以通过LGDT指令将GDT的入口地址装入此寄存器,从此以后,CPU就根据此寄存器中的内容作为GDT的入口来访问GDT了。

GDT表相当于一个64bit的数组,GDT的结构图略。

分段模型下,内存的分配是不定长的,时间长了,内存空间就会碎片化,就有可能出现一种情况:内存空间是有的,但都是小块,无法分配给某个任务。为了解决这个问题,在支持分页功能后,分页功能将物理内存空间划分成逻辑上的页。页的大小是固定的,一般为 4KB,通过使用页,可以简化内存管理。未开启页功能时,线性地址就是物理地址;当页功能开启时,段部件产生的地址就不再是物理地址了,而是线性地址,线性地址还要经页部件转换后,才是物理地址。线性地址的概念用来描述任务的地址空间。32位保护模式中,每个任务都拥有4GB的虚拟内存空间,就像一段平直的线段,因此叫线性地址空间。相应地,由段部件产生的地址,就对应着线性地址空间上的每一个点,这就是线性地址。

CPU的寻址方式

寄存器寻址,当操作数不放在内存中,而是放在CPU的寄存器中时,从寄存器中取操作数的方式称为寄存器寻址。

mov ax, bx ;寄存器直接寻址

mov ax, [bx] ;寄存器间接寻址”

立即数寻址,源操作数是常数,是相对于其他寻址方式中处理器需要从寄存器或内存中获取操作数的方式而言的。

内存直接寻址,就是直接在操作数中给出的数字作为内存地址,通过中括号的形式告诉CPU取此地址作为操作数。直接寻址和立即数寻址的区别在于,立即数寻址中的数字是直接拿来用作操作数,而直接寻址中的数字则是用来近一步寻址的。

内存基址寻址,add word[bx], 0x1234 ;将0x1234加上内存地址ds:bx处的值后再存入内存地址ds:bx中;

内存变址寻址,mov [di], ax ;将寄存器ax的值存入ds::di指向的内存;

内存基址变址寻址,mov [bx+di], ax ;将ax中的值存入以ds为段基址,bx+di为偏移地址的内存中。

文件系统(File System)

1、文件系统及基本格式

文件系统是操作系统用于明确存储设备(磁盘)或分区上的文件的方法和数据结构,即在存储设备上组织文件的方法。操作系统中负责管理和存储文件信息的软件机构称为文件管理系统,简称文件系统。

文件系统常见的有四种:FAT16、FAT32、NTFS、ExFAT。

“FAT12是DOS时代就开始使用的文件系统(File System),直到现在仍然在软盘上使用。

FAT12软盘的被格式化后为:有2个磁头,每个磁头80个柱面(磁道),每个柱面有18个扇区,每个扇区512个字节空间。标准软盘的总空间为:2 * 80 *18 * 512=1474560B=1440K=1.44M。

FAT1和FAT2是两个完全相同的FAT表,每个FAT占用9个扇区。其中FAT1占用1—9扇区,FAT2占用10—18扇区,共2880个扇区。”

操作系统启动时,BIOS检查磁盘的第一个扇区,并根据此扇区(大小为512B)的末尾是否以0X55和0XAA这2个字节为结束标志,来判断其是否为引导扇区。如果是,则将此扇区的数据拷贝至,内存地址从0X7C00到0X7DEE的内存中。

2、引导扇区(Boot Sector)

通常指设备(硬盘)的第一个扇区,用于加载并转让处理器控制权给操作系统。硬盘的0柱面、0磁头、1扇区称为主引导扇区,也叫主引导记录MBR,该记录占用512个字节,它用于硬盘启动时将系统控制权转给用户指定的、在分区表中登记了某个操作系统分区。

硬盘(严格来说是所有可引导的存储介质)上的第一个扇区,即引导扇区,大小为512字节,主要包含了3部分:

1、MBR(Master Boot Record,主引导记录),446字节。

2、DPT(Disk Partition table,磁盘分区表),64字节。

每16个字节表示一个分区,这16个字节的含义如下:

第1个字节,1,0x00表示非活动分区,0x80表示活动分区,四个分区只有一个是激活的;

第2~4字节,3,该分区第一个扇区的物理位置;

第5个字节,1,分区类型,0x83就是Linux分区;

第6~8字节,3,该分区最后一个扇区的物理位置;

第9-12字节,4,该分区第一个扇区的逻辑地址;

第13-16字节,4,该分区的扇区总数;

3、BRID(Boot Record ID,引导记录标识),2字节。

主要作用就是判断该设备是否可以用于启动。BIOS按照“启动顺序”,把控制权转交给排在第一位的储存设备。这时,计算机读取该设备的第一个扇区,也就是读取最前面的512个字节。如果这512个字节的最后两个字节是0x55和0xAA,表明这个设备可以用于启动;如果不是,表明设备不能用于启动,控制权于是被转交给“启动顺序”中的下一个设备。

其实主引导记录的作用就是告诉计算机到硬盘的哪一个位置去找操作系统。

操作系统

操作系统启动顺序

Linux操作系统启动顺序:

1、按启动按钮后通电;

2、BIOS自检通过;

3、BIOS发现了Boot Sector ,并将引导扇区的内容读到内存的0000:7C00处,并检查内存地址0000:7DFE的内容为:0xAA55,如果不是,则重新寻找;

4、BIOS将控制权彻底交给了Boot Sector的这段代码;在0000:7C00处执行MBR;

5、Bootloader:grub引导菜单;

6、加载内核 Kernel(ramdisk) ;

7、启动init进程,依据inittab文件设定运行级别;

8、init进程,执行rc.sysinit文件;

9、启动内核模块,执行不同级别的脚本程序;

10、执行/etc/rc.d/rc.local;

11、启动mingetty,进入系统登陆界面。

Windows操作系统启动顺序:

1、按启动按钮后通电;

2、BIOS自检通过;

3、BIOS发现了Boot Sector ,并将引导扇区的内容读到内存的0000:7C00处,并检查内存地址0000:7DFE的内容为:0xAA55,如果不是,则重新寻找;

4、BIOS将控制权彻底交给了Boot Sector 的这段代码;在0000:7C00处执行MBR;MBR接着从分区表( Partition Table )中找到第一个活动分区( Active Partition,一般是C盘分区),然后按照类似方式读取并执行这个活动分区的引导扇区( Partition Boot Sector ),而引导扇区将负责读取并执行NTLDR( NT LoaDeR,NT Loader,Windows系统加载程序)。

5、最后将主动权移交给了windows操作系统。

实现操作系统HelloWorld功能

实现功能:计算器启动,加载运行该程序,屏幕打印”New Coronavirus Operate System!”

汇编代码:

 %define _BOOT_DEBUG_

%ifdef _BOOT_DEBUG_
 org 0100h           ; 调试文件,做成.COM文件,可用于调试
%else
 org 07c00h          ; 告诉编译器程序加载到7c00处
%endif

 mov ax,cs          ;
 mov ds,ax          ;
 mov es,ax          ;
 call DispStr       ; 调用显示字符串例程(作用类似于函数,但含义更为丰富一些)
 jmp $             ; 无限循环
 
DispStr:
 mov ax,BootStr     ; 
 mov bp,ax          ; es:bp=串地址
 mov cx,16          ; cx=串长度
 mov ax,01301h      ; ah=13,al=01h
 mov bx,000ch       ; 页号为0 (bh=0) 黑底红字(bl=0ch,高亮)
    mov dl,0
    int 10h            ; 10h号中断
    ret
    
BootStr:
    db "New Coronavirus Operate System!"
    
    times 510-($-$$) db 0          ; 填充剩下的空间,使生成二进制代码
                                   ; 正好为512字节
    dw 0xaa55                      ; 结束标志  

编译命令:nasm os.asm -o os.bin

“运行说明:os.bin文件正好为512字节;

1、写入硬盘的第0个扇区,BIOS启动菜单中设置启动。

2、Bochs软件模拟测试,加载os.bin文件启动即可。

文章来源:智云一二三科技

文章标题:Java,CPU、汇编语言、内存管理、文件系统、操作系统启动

文章地址:https://www.zhihuclub.com/179130.shtml

关于作者: 智云科技

热门文章

网站地图