Lua 是由巴西里约热内卢天主教大学(Pontifical Catholic University of Rio de Janeiro)里的一个研究小组于1993年开发的一种轻量、小巧的脚本语言,用标准 C 语言编写,其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。
x86 系统中的保护模式,给系统的安全性提供了很大的保障,但是在我们之前的文章中,一直都淡化了特权级别这个概念。
本篇博客来给大家介绍怎样使用Lua这门语言来开发一个简单的小游戏—记数字踩白块。
Intel 微处理器的段机制是从8086 开始提出的, 那时引入的段机制解决了从CPU 内部 16 位地址到20 位实地址的转换。为了保持这种兼容性,386 仍然使用段机制,但比以前复杂。 因此,Linux 内核的设计并没有全部采用Intel 所提供的段方案,仅仅有限度地使用 了一下分段机制。这不仅简化了Linux 内核的设计,而且为把Linux 移植到其他平台创造了 条件,因为很多RISC 处理器并不支持段机制。但是,对段机制相关知识的了解是进入Linux 内核的必经之路。
本文以linux0.11版本为基础,分析进程的内存布局,现代版本已经发生比较大的变化,都是很多原理都是类似的。 系统维护了一个全局的数据结构叫GDT( Global Descriptor Table),他保存了所有进程的代码段数据段的一些信息。系统有专门的寄存器保存了GDT的地址,叫GDTR。GTDR的格式如下。
这一篇大致说一下进程的创建,有兴趣的可以参考之前的一些文章或者直接上代码https://github.com/theanarkh/read-linux-0.11。
Lua 实现的一个简单的 LRU 缓存,适合在 Lua 空间里直接缓存较为复杂的 Lua 数据结构:
进程的地址有三种,分别是虚拟地址(逻辑地址)、线性地址、物理地址。在分析之前先讲一下进程执行的时候,地址的解析过程。在保护模式下,段寄存器保存的是段选择子,当进程被系统选中执行时,会把tss和ldt等信息加载到寄存器中,tss是保存进程上下文的,ldt是保存进程代码和数据段的首地址偏移以及权限等信息的。假设当前执行cs:ip指向的代码,系统根据ldt的值从gdt中选择一个元素,里面保存的是idt结构的首地址。然后根据cs的值选择idt表格中的一项,从而得到代码段的基地址和限长,用基地址加上ip指向的偏移得到一个线性地址,这个线性地址分为三个部分,分别是页目录索引,页表索引,物理地址偏移。然后到页目录吧和页表中找到物理地址基地址,再加线性地址中的偏移部分,得到物理地址。下面我们看看这些内容是怎么设置的,使得执行的时候能正确找到我们想要的地址去执行代码。我们从fork函数开始。到进程被调度执行时所发生的事情。fork函数的具体调用过程之前已经分析过。下面贴一下主要的代码。
注:本分类下文章大多整理自《深入分析linux内核源代码》一书,另有参考其他一些资料如《linux内核完全剖析》、《linux c 编程一站式学习》等,只是为了更好地理清系统编程和网络编程中的一些概念性问题,并没有深入地阅读分析源码,我也是草草翻过这本书,请有兴趣的朋友自己参考相关资料。此书出版较早,分析的版本为2.4.16,故出现的一些概念可能跟最新版本内核不同。
因为程序是分段在内存中存放的,因此需要额外的空间记录每个段的存放位置和占用大小,这就引出了段表,这里的段表又被称为LDT表,每个进程都对应一个LDT表:
---- 保护模式 什么实模式和保护模式 这是CPU的两种工作模式,解析指令的方式不同。 在实模式下,16位寄存器需要通过段:偏移的方法才能达到1MB的寻址能力。 物理地址 = 段值 x 16 + 偏移 此时段值还可以看成地址的一部分,段值为XXXXh表示以XXXX0h开始的一段内存。 在保护模式下,CPU有着巨大的寻址能力,并为操作系统提供了虚拟内存和内存保护。 虽然物理地址的仍然用上面的公式表示,但此时“段”的概念发生了变化,它变成了一个索引,指向一个数据结构的一个表项,表项中详细定义了段的
本文讲解系统的进程管理相关内容,系统的进程管理是有关系统的所有进程的调度、排序、分配资源、创建、销毁等,是比较重要的内容。
每一个进程都有一张段表LDT。整个系统有一张GDT表。且整个系统仅仅有一个总页表。
经过多篇文章的介绍,我们对 32 位保护模式已经有了很深的认识,尤其是分段机制以及由此带来的对内存的保护。 进军保护模式 保护模式进阶 — 再回实模式
本文涉及的硬件平台是X86,如果是其他平台的话,如ARM,是会使用到MMU,但是没有使用到分段机制; 最近在学习Linux内核,读到《深入理解Linux内核》的内存寻址一章。原本以为自己对分段分页机制已经理解了,结果发现其实是一知半解。于是,查找了很多资料,最终理顺了内存寻址的知识。现在把我的理解记录下来,希望对内核学习者有一定帮助,也希望大家指出错误之处。
本节继续探讨Java 8的新特性,主要是介绍Java 8对日期和时间API的增强,关于日期和时间,我们在之前已经介绍过两节了,32节介绍了Java 1.8以前的日期和时间API,主要的类是Date和Calendar,由于它的设计有一些不足,业界广泛使用的是一个第三方的类库Joda-Time,关于Joda-time,我们在33节进行了介绍。Java 1.8学习了Joda-time,引入了一套新的API,位于包java.time下,本节,我们就来简要介绍这套新的API。 我们先从日期和时间的表示开始。 表示
进程,这个词大家应该耳熟能详了,那进程是什么呢?我们说程序一般是外存上的一个可执行文件,而进程就是这个可执行文件在内存中的一个执行实例。概念始终只会是一个抽象的概念,进程系列文章通过 $xv6$ 的实例来将进程这个概念具象化。本篇主要介绍进程涉及到的一些数据结构,废话不多说,直接来看
理论上来讲,可以把那些可靠性介于操作系统和应用程序之间的程序安排在这两个特权级上。
LocalDate、LocalTime、LocalDateTime 类的实例是不可变的对象,分别表示使用ISO-8601日历系统的日期、时间、日期和时间。它们提供了简单的日期或时间,并不包含当前的时间信息。也不包含与时区相关的信息。
操作系统接口并不是直接暴露给用户使用的,用户是通过应用软件间接调用到操作系统接口的。
PS:原先实模式下的各个段寄存器作为保护模式下的段选择器,80486中有6个(即CS,SS,DS,ES,FS,GS)80位的段寄存器。由选择器CS对应表示的段仍为代码段,选择器SS对应表示的段仍为堆栈段。
多线程编程是现代软件技术中很重要的一个环节。要弄懂多线程,这就要牵涉到多进程?当然,要了解到多进程,就要涉及到操作系统。不过大家也不要紧张,听我慢慢道来。这其中的环节其实并不复杂。
---- 我们可以把一个单独的任务所用到的所有东西封装在一个LDT中,这种思想是多任务处理的雏形。 多任务所用的段类型如下图,使用LDT来隔离每个应用程序任务的方法,正是关键保护需求之一:
Java新时间API中有三个特别重要的类,分别是Instant、LocalDateTime、ZonedDateTime,它们分别对应到上一篇文章中讲到的时间概念为:机器时间、无时区的本地时间、有时区的本地时间。
摘 要:本文通过解剖Linux操作系统的虚拟存储管理机制,说明了Linux虚拟存储的特点、虚拟存储器的实现方法,并基于Linux Kernel Source 1.0,详细分析有关虚拟存诸管理的主要数据结构之间的关系。
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u014688145/article/details/50608829
http://bbs.chinaunix.net/thread-2083672-1-1.html
此前我们对操作系统中的分段、分页机制以及虚拟地址、逻辑地址、线性地址、物理地址进行了较为详细的介绍。 操作系统的内存管理 — 分段与分页、虚拟地址、逻辑地址、线性地址、物理地址
不论是在 x86 平台上,还是在嵌入式平台上,系统的启动一般都经历了 bootloader 到 操作系统,再到应用程序,这样的三级跳过程。
操作系统 内存使用与分段--10 如何让内存用起来? 那就让首先程序进入内存 重定位: 修改程序中的地址(是相对地址) 程序载入后还需要移动… 重定位最合适的时机 - 运行时重定位 整理一下思路 引入
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
看完了进入内核前的工作后,我网络编程课的抄写作业自然是可以圆满完成啦,不过看了一部分后觉得确实很有意思,所以也是决定继续看下去,并且计划看完linux源码后跟着MIT6.s081写一个小的操作系统内核,希望我能够在6.29之前完成这个工作哈哈也就是我开始军训之前,补军训确实是个令人苦恼的事情。
常用业务场景有:判断奇偶数,判断是否为2的整数次幂,左移,右移,两数交换,取相反数,取绝对值。
以上就是对GDT表或者 LDT表的描述 总结来说 GDT或者LDT 就是一块内存. 也可以看成一个数组. 数组的每一项其实保存的都是段描述符 段选择子就是下标 3.1.2 GDTR寄存器与GDT表了解. 根据Inter手册所属. GDTR寄存器 保存了 GDT的 32位基地址 和16位表界限 基地址指的就是GDT从0字节开始的线性地址.可以理解为就是数组首地址. 表界限.可以理解为就是数组的大小. 所以说GDTR 寄存器是一个48位寄存器 按照C语言结构来来表是就如下 struct GDTR { DWORD *GdtBase, SHORT limit; } LGDT 与SGDT 汇编指令 分别是用来获取和保存 GDTR寄存器的. 电脑开机之后,通电之后.GDT就开始初始化了. 总结:
哈喽!大家好,我是小简。今天开始学习《Java8-新特性》,此系列是我做的一个 “Java 从 0 到 1 ” 实验,给自己一年左右时间,按照我自己总结的 Java-学习路线,从 0 开始学 Java 知识,并不定期更新所学笔记,期待一年后的蜕变吧!<有同样想法的小伙伴,可以联系我一起交流学习哦!>
分段内存段间的内存空间太大(16位64k),碎片太多,段+偏移转换为线性地址后,通过分页管理,映射到新的地址空间,页目录+页表+页内偏移(12位4k),减小内存间隙的大小
所谓的淘汰策略就是: 我们redis中的数据都没有过期,但是内存有大小,所以我们得淘汰一些没有过期的数据!!
所以执行fork函数就会执行system_call函数,但是在这之前,还有些事情需要做,就是保存现场。下面是操作系统执行系统调用前,在内核栈里保存的寄存器,这个压入的寄存器和iret中断返回指令出栈的寄存器是对应的。其中ip指向的是调用系统调用返回后的下一句代码。
首先,要想明白Lambda表达式就要先明白函数式接口,所以,咱们先来了解一下什么是函数式接口吧!
execve函数是操作系统非常重要的一个函数,他使得程序变成进程成为可能。下面我们通过do_execve的实现,了解一下程序变成进程的过程。首先do_execve是一个系统调用。之前分析过系统调用的过程。这里就不详细说了。直接从sys_execve函数开始。
Lambda除了在for循环遍历中使用外,它还可以代替匿名的内部类。比如下面这个例子的线程创建:
这样一来每次都要写上具体的实现方法 a+b,如果需求变更,则每一处实现都需要更改,基于这种情况,可以将后续的是实现更改为已定义的 方法,需要时直接调用就行
经过一系列的文章,我们通过汇编语言,体验了保护模式下分段、分页、特权级跳转、中断、异常等机制。 那么,事到如今,你是否已经深谙保护模式的设计之道了呢?究竟什么是保护模式,保护模式又在“保护”什么呢?他为了什么诞生,又和实模式有什么区别呢? 本文我们就来详细总结一下。
学习Windows程序设计也有一些时间了,为了记录自己的学习成果,以便以后查看,我希望自己能够坚持写下一系列的学习心得,对自己学习的内容进行总结,同时与大家交流。因为刚学习所以可能有的地方写不不正确,希望大家能够指出。
能否站在程序员的视角看来,程序分段存放在内存上的模样是连续的,但是站在物理内存视角看来,却是分页管理的呢?
本篇主要讲述是Java中JDK1.8的一些新语法特性使用,主要是Lambda、Stream和LocalDate日期的一些使用讲解。
上一节,我们开发了一个流氓程序,当他运行起来后,能够把自己的数据写入到另一个进程的数据内存中。之所以产生这样的漏洞,是因为被入侵进程的数据段所对应的全局描述符在全局描述符表中。恶意程序通过在全局描述符表中查找,当找到目标程序的内存描述符后,将对应的描述符加载到自己的ds寄存器里,于是恶意程序访问内存时,就相当于读写目标程序的内存。 要防范此类入侵,最好的办法是让恶意程序无法读取自己内存段对应的描述符,但是如果不把自己的内存描述符放置在全局描述符表中的话,还能放哪里呢?Intel X86架构还给我们提供了另一
领取专属 10元无门槛券
手把手带您无忧上云