
masm
文章平均质量分 68
sinolover
完成项目,就要软硬兼施
展开
-
【转】RAX,eax,ax,ah,al 关系
转自:RAX,eax,ax,ah,al 关系_迪迦 • 奥特曼-优快云博客_rax和eax|63..32|31..16|15-8|7-0| |AH.|AL.| |AX.....| |EAX............||RAX...................|一般寄存器:AX、BX、CX、DXAX:累积暂存器,BX:基底暂存器,CX:计数暂存器,DX:资料暂存器索引暂存器:SI、DISI:来源索引暂存器,DI原创 2021-12-20 19:10:43 · 3504 阅读 · 0 评论 -
《操作系统真象还原》-阅读笔记(上)
第一章配置bochs,进入bochs simulator后一直是黑屏,原来默认是调试模式,需要输入C(continue)来让调试继续。第二章主讲MBR及进入MBR前的步骤1.实模式只能访问1MB的内存空间。2.BIOS在ROM中。3.开机上电后CS:IP指向内存0xfff0,这里有个跳转语句,转到fe05b才是真正的BIOS程序,之后检测内存,显卡灯,建立数据结构,中断向量表和填...转载 2019-07-01 16:02:15 · 833 阅读 · 1 评论 -
一步步编写操作系统 57 门、调用门与RPL序 2
接上文:提供了4种门的原因是,它们都有各自的应用环境,但它们都是用来实现从低特权级的代码段转向高特权级的代码段,咱们这里也只讨论有关特权级的功用:1.调用门call和jmp指令后接调用门选择子为参数,以调用函数例程的形式实现从低特权向高特权转移,可用来实现系统调用。call指令使用调用门可以实现向高特权代码转移,jmp指令使用调用门只能实现向平级代码转移。2.中断门以int指令主动...转载 2019-07-09 15:35:47 · 428 阅读 · 0 评论 -
一步步编写操作系统 58 门、调用门与RPL序 3
接前文:并不是任何当前特权级都可以使用门结构, 在使用门结构之前,处理器要例行公事做特权级检查,参与检查的不只是CPL和DPL,还有RPL,为了说清楚这个检查过程,咱们得先介绍下RPL。RPL,即请求特权级,为了解释清楚,咱们得多花点工夫好好说道说道。我们本节始终在说特权级转移,处理器从一个特权级转移到另一个特权级,任意时刻处理器所处的特权级称为当前特权级。重复叙述的目的是强调当前特权...转载 2019-07-09 15:36:25 · 331 阅读 · 0 评论 -
一步步编写操作系统 59 cpu的IO特权级1
在保护模式下,处理器中的“阶级”不仅体现在数据和代码的访问,还体现在指令中。一方面将指令分级的原因是,有些指令的执行对计算机有着严重的影响,它们只有在0特权级下被执行,因此被称为特权指令(Privilege Instruction)。比如hlt指令,它可以让计算机停机,处理器只信任操作系统,所以它不得不放在0特权级下。同类的指令还有lgdt,lidt,ltr,popf等,这些对计算机的正常运行...转载 2019-07-09 15:37:16 · 533 阅读 · 0 评论 -
一步步编写操作系统 60 cpu的IO特权级2 什么是驱动程序
用户程序可以在由操作系统加载时通过指定整个eflags设置,操作系统如何设置自己的IOPL呢,即使内核IOPL为0也得写进去eflags寄存器中才生效。可惜的是,没有直接读写eflags寄存器的指令,不过可以通过将栈中数据弹出到eflags寄存器中来实现修改。可以先用pushf指令将eflags整体压入栈,然后在栈中修改相应位,再用popf指令弹出到eflags寄存器中。另外一个可利用栈的指令是i...原创 2019-07-10 09:17:41 · 526 阅读 · 0 评论 -
一步步编写操作系统 61 任务状态段 TSS
I/O位图是位于TSS中的,它可以存在也可以不存在,它只是用来设置对某些特定端口的访问,没有它的话便默认为禁止访问所有端口。正是由于它可有可用,所以TSS的段界限TSS limit(即实际大小-1)并不固定。当TSS中不包括I/O位图时,TSS只有104字节大小。话说回来了,当处理器执行某些IO指令时,若当前特权级比IOPL低,处理器就会认为也许只是给当前任务单独放行了某些端口,于是它就到TSS中...转载 2019-07-10 09:17:52 · 671 阅读 · 0 评论 -
一步步编写操作系统 46 linux的elf可执行文件格式1
ELF文件格式依然是分为文件头和文件体两部分,只是该文件头相对稍显复杂,类似层次化结构,先用个ELF header从“全局上”给出程序文件的组织结构,概要出程序中其它头表的位置大小等信息,如程序头表的大小及位置、节头表的大小及位置。然后,各个段和节的位置、大小等信息再分别从“具体的”程序头表和节头表中予以说明。ELF格式的作用体现在两方面,一是链接阶段,另一方面是运行阶段,故它们在文件中组织布...转载 2019-07-04 18:36:20 · 416 阅读 · 0 评论 -
一步步编写操作系统 45 linux的elf可执行文件中的段和节
接上文,为了描述清楚文件格式的本质,咱们先从最基本的“段”说起。程序中最重要的部分就是段(segment)和节(section),它们是真正的程序体,是真真切切的程序资源,所以下面的说明咱们以它们为例。程序中有很多段,如代码段和数据段等,同样也有很多节,段是由节来组成的,多个节经过链接之后就被合并成一个段了,之前咱们有通过实例解释过segment和section之间的关系。段和节的信息也是...转载 2019-07-04 18:37:07 · 1129 阅读 · 0 评论 -
一步步编写操作系统 56 门、调用门与RPL序 1
小弟多次想把调用门和RPL分开单独说,但几次尝试都没有成功,我发现它们之间是紧偶合、密不可分,RPL的产生主要是为解决系统调用时的“越权”问题,系统调用的实现方式中,以调用门和中断门最为适合。由于以后我们将用中断门实现自己的系统调用,故在此本着扩充知识面的目的给大伙儿介绍调用门,通过调用门的实例,让大伙儿理解特权级那点事儿。处理器只有通过“门结构”才能由低特权级转移到高特权级,处理器就是这样设...原创 2019-07-09 15:32:37 · 391 阅读 · 0 评论 -
换种方法学操作系统,轻松入门Linux内核
计算机已成为现代人日常工作、学习和生活中必不可少的工具。操作系统是计算机之魂,作为用户使用计算机的接口,它负责调度执行各个用户程序,使计算机完成特定的任务;作为计算机硬件资源的管理者,它负责协调计算机中各类设备高效地工作。操作系统的重要性不言而喻。对于软件工程师,理解操作系统的工作原理和关键机制是设计高质量应用程序的前提,但要做到这一点是十分困难的。一方面,操作系统设计涉及计算机科学与工程...转载 2019-07-02 19:14:54 · 352 阅读 · 0 评论 -
一步步编写操作系统 35 内存为何要分页
一直以来我们都直接在内存分段机制下工作,目前未出问题看似良好,的确目前咱们的应用过于简单了,就一个loader在跑,能出什么问题呢。可是想像一下,当我们物理内存不足时会怎么办呢?比如系统里的应用程序过多、或者内存碎片过多无法容纳新的进程、或者曾经被换出到硬盘中的内存段需要再次重新装到内存,可是内存中找不到合适大小的内存区域怎么办?也许有人会说,这简单啊,停止想像呗…….嘿嘿,开玩笑而已,问题还是要...转载 2019-07-02 19:18:43 · 1033 阅读 · 0 评论 -
《操作系统真象还原》-阅读笔记(中)
第七章操作系统是由中断驱动的。中断分为外部中断和内部中断。外部中断分为可屏蔽中断和不可屏蔽中断,内部中断分为软中断和异常。外部中断来自CPU外部的中断。可屏蔽中断:通过INTR引脚进入CPU,外部设备如硬盘、网卡、打印机等发出的中断CPU可以不理会,因为不会宕机。Linux把中断分为上半部和下半部分开处理,把中断立即需要执行的部分划分到上半部,不紧急的部分划分到下半部。上半部是...转载 2019-07-01 16:02:21 · 488 阅读 · 0 评论 -
《操作系统真象还原》-阅读笔记(下)
第十一章任意进程的页目录表第0~767个页目录项属于用户空间,指向用户页表。第768~1023个页目录项指向内核页表。每创建一个新的用户进程,就将内核页目录项复制到用户进程的页目录表,其次需要把用户页目录表中最后一个页目录项更新为用户进程自己的页目录表的物理地址。每个进程有自己单独的位图,存储在进程pcb中的userprog_vaddr中。LDT当前运行的任务,其LDT位于LDTR指向的地...转载 2019-07-01 16:02:27 · 364 阅读 · 0 评论 -
一步步编写操作系统 30 cpu的分支预测简介
人在道路的分岔口时要预测哪条路能够到达目的地,面对众多选择时,计算机也一样要抉择,毕竟计算机的运行方式是以人的思路来设计的,计算机中的抉择其实就是人在抉择。cpu中的指令是在流水线上执行。分支预测,是指当处理器遇到一个分支指令时,是该把分支左边的指令放到流水线上还是把分支右边的指令放在流水线上呢?如C语言程序中的if、switch、for等语言结构,编译器将它们编译成汇编代码后,在汇编一级...转载 2019-06-30 14:27:43 · 383 阅读 · 0 评论 -
一步步编写操作系统 31 cpu的分支预测 下
让我们说说预测的算法吧。对于无条件跳转,没啥可犹豫的,直接跳过去就是了。所谓的预测是针对有条件跳转来说的,因为不知道条件成不成立。最简单的统计是根据上一次跳转的结果来预测本次,如果上一次跳转啦,这一次也预测为跳转,否则不跳。最简单的方法是2位预测法。用2位bit的计数器来记录跳转状态,每跳转一次就加1,直到加到最大值3就不再加啦,如果未跳转就减1,直到减到最小值0就不再减了。当遇到跳转指令...转载 2019-07-01 16:02:35 · 372 阅读 · 0 评论 -
一步步编写操作系统 32 linux内核获取内存容量的方法
操作系统是计算机硬件的管家,它不仅要知道自己的安装了哪些硬件,还得给出有效得当的管理措施,按照预定的一套管理策略使硬件资源得到合理的运用。但管理策略只是逻辑上的东西,是操作系统自圆其说的一套管理资源的方法,管理再漂亮,没有硬件支撑也无能为力,真正干活的都是底层。保护模式最“大”的特点就是寻址空间“大”,在进入保护模式之后,我们将接触到虚拟内存、内存管理等。但这些和内存有关的概念都是建立在物理内...转载 2019-07-01 16:02:41 · 778 阅读 · 1 评论 -
一步步编写操作系统 33 利用bios中断0x15子功能0xe820获取内存
咱们先介绍0xE820子功能,这是最灵活的内存获取方式。bios中断 0x15的子功能0xE820能够获取系统的内存布局,由于系统内存各部分的类型属性不同,bios就按照类型属性来划分这片系统内存,所以这种查询则呈迭代式,每次bios只返回一种类型的内存信息,直到将所有内存类型返回完毕。子功能0xE820的强大之处是返回的内存信息较丰富,包括多个属性字段,所以需要一种格式结构来组织这些数据。内...转载 2019-07-01 16:03:00 · 1002 阅读 · 0 评论 -
一步步编写操作系统 34 内核利用bios中断获取物理内存大小
接上文,另一个获取内存容量的方法是bios 0x15中断的子功能0xE801。此方法虽然简单,但功能也不强大,最大只能识别4G内存,不过这对咱们32位地址总线足够了。稍微有点不便的是,此方法检测到的内存是分别存放到两组寄存器中的。低于15MB的内存是以1KB为单位大小来记录,单位数量在寄存器AX和CX中记录,其中AX和CX的值是一样的,所以在15MB空间以下的实际内存容量=AX*1024。AX...转载 2019-07-01 16:03:08 · 924 阅读 · 0 评论 -
一步步编写操作系统 45 用c语言编写内核2
在linux下用于链接的程序是ld,链接有一个好处,可以指定最终生成的可执行文件的起始虚拟地址。它是用-Ttext参数来指定的,所以咱们可以执行以下命令完成链接:ld kernel/main.o -Ttext 0xc0001500 -e main -o kernel/kernel.bin从左到右说一下参数,-Ttext 指定起始虚拟地址为0xc0001500,这个地址是设计好的,为什么用这...转载 2019-07-03 10:05:03 · 663 阅读 · 0 评论 -
一步步编写操作系统 47 elf格式文件分析实验
在上一节中,我们讲述了elf格式的部分理论知识,为什么是部分呢?因为我们本着“够用”的原则,只把我们需要了解的部分说完啦。不过,我相信大部分同学仅仅凭上一节中的理论知识还是领悟不到elf本质,咱们在本节开始分析前面咱们写过的“内核”,让大家看清elf文件的每一个字节。为了让大家看清楚elf文件内部,咱们要用之前的xxd命令,为了方便使用,如很久很久以前所述,已经将其封装成了xxd.sh脚本,参...转载 2019-07-04 18:38:14 · 426 阅读 · 0 评论 -
一步步编写操作系统 49 加载内核2
内核文件kernel.bin是elf格式的二进制可执行文件,初始化内核就是根据elf规范将内核文件中的段(segment)展开到(复制到)内存中的相应位置。在分页模式下,程序是靠虚拟地址来运行的,无论是内核还是用户程序,它们对cpu来说都是指令或数据、没什么区别,交给cpu的指令或数据的地址一律被认为是虚拟地址。坦白说,内核文件中的地址是在编译阶段确定的,里面都是虚拟地址,程序也是靠这些虚拟地址来...原创 2019-11-04 18:04:29 · 452 阅读 · 0 评论 -
一步步编写操作系统 75 从显卡读取光标位置1
我们在打印字符时,通常都不用指定字符显示的坐标位置,大家也没觉得有什么奇怪,原因是字符是在当前光标的位置处显示的,而且光标的位置会一直更新顺延,我们的字符一直跟着光标走,似乎光标就是字符的导航一样,而我们已经习惯了跟随光标。我想大伙儿已经清楚了光标和字符的关系了,对,它们的关系就是没有任何关系^_^。“光标在哪字符就在哪”,这是我们人为有意设置的,我们是在光标处打印字符。也就是说,我们也可以不在光...转载 2019-07-18 18:29:02 · 360 阅读 · 0 评论 -
一步步编写操作系统 76 用汇编语言编写字符打印函数
之前咱们介绍显卡上那么多的寄存器终于发挥用处了,我们看看前文中介绍的表CRT Controller Data Registers中索引为0Eh的 Cursor Location High Register寄存器和索引为0Fh的Cursor Location Low Register寄存器,这两个寄存器都是8位长度。分别用来存储光标坐标的低8位和高8位地址。访问CRT controller寄存器...翻译 2019-07-18 18:29:33 · 481 阅读 · 0 评论 -
一步步编写操作系统 77 内联汇编与AT&T语法简介
内联汇编之前和大家介绍过了一种汇编方法,就是C代码和汇编代码分别编译,最后通过链接的方式结合在一起形成可执行文件。另一种方式就是在C代码中直接嵌入汇编语言,强大的GCC无所不能,咱们本节要学习的就是这一种,它称为内联汇编。其实还有另外一种,就是那些技术大牛才能玩得转的方式,将c代码编译为汇编代码后,再修改汇编代码。什么是内联汇编内联汇编称为inline assembly,GCC...转载 2019-07-18 18:31:46 · 337 阅读 · 0 评论 -
一步步编写操作系统 78 intel汇编与AT&T汇编语法区别
本节咱们介绍下intel汇编语法和at&t汇编语法的区别。以上表中未列出这两种语法在内存寻址方面的差异,个人觉得区别还是很大的,下面单独说说。在Intel语法中,立即数就是普通的数字,如果让立即数成为内存地址,需要将它用中括号括起来,“[立即数]”这样才表示以“立即数”为地址的内存。而AT&T认为,内存地址既然是数字,那数字也应该被当作内存地址,所以...转载 2019-07-18 18:33:34 · 369 阅读 · 0 评论 -
一步步编写操作系统 65 标准调用约定stdcall 汇编实战
因为c语言遵循的调用约定是cdecl,咱们也自然要遵守cdecl约定了。不过为了起到对比的作用,除了介绍cdecl外,也会介绍下stdcall。既然咱们用的是调用约定是cdecl,那对它的介绍最好让它离下一节的内容近一些,所以先说一下咱们不用的stdcall吧^_^,其实这两个差别就在于由谁来回收栈空间。stdcall的调用约定意味着:调用者将所有参数从右向左入栈; 被调用者清理参数...原创 2019-07-23 15:52:21 · 340 阅读 · 0 评论 -
一步步编写操作系统 79 在c代码中内联汇编
基本内联汇编是最简单的内联形式,其格式为:asm [volatile] (“assembly code”)各关键字之间可以用空格或制表符分隔也可以紧凑挨在一起不分隔,各部分意义如下:关键字asm用于声明内联汇编表达式,这是内联汇编固定的部分,不可少。asm和__asm__是一样的,是由gcc定义的宏:#define __asm__ asm。因为gcc有个优化选项-O,可以指定优...原创 2019-09-10 16:44:10 · 221 阅读 · 0 评论 -
一步步编写操作系统80 扩展内联汇编1
由于基本内联汇编功能太薄弱了,所以才对它进行了扩展以使其功能强大。不过,易用性往往与功能强弱是成正比的,如您所料,扩展内联汇编确实有点难,但在求知欲的驱使下,就让咱们痛并快乐着吧。gcc本身是个c编译器,要让其支持汇编语言,必然牵扯到以下问题:在内联汇编代码插入点之前的c代码,其编译后也要被分配寄存器等资源,插入的汇编代码也要使用寄存器,这是否会造成资源冲突? 汇编语言如何访问c代码中的...原创 2019-09-10 16:45:42 · 269 阅读 · 0 评论 -
一步步编写操作系统81 at&t内嵌汇编语法
内联汇编的格式也变得让人生畏了,感觉既不像C语言,也不像汇编语言,似乎是一种中间产物,不信您看:asm [volatile] (“assembly code” : output : input : clobber/modify)和前面的基本内联汇编相比,扩展内联汇编在圆括号中变成了4部分,多了output,input,和clobber/modify三项。其中的每一部分都可以省略,甚至包括a...原创 2019-09-10 16:46:13 · 316 阅读 · 0 评论 -
一步步编写操作系统 71 直接操作显卡,编写自己的打印函数71-74
一直以来,我们在往屏幕上输出文本时,要么利用bios中断,要么利用系统调用,这些都是依赖别人的方法。咱们还用过一个稍微有点独立的方法,就是直接写显存,但这貌似又没什么含量。如今我们要写一个打印函数了,似乎,我们马上就要站起来了之前我们讲述了有关显卡的知识,但当时怕影响兄弟们的学习积极性,我们并没有说把有关显卡的寄存器罗列出来。话说,出来混早晚要还的,躲得过初一躲不过十五。如今我们需要通过端口来...转载 2019-07-18 18:25:14 · 526 阅读 · 0 评论 -
一步步编写操作系统 69 汇编语言和c语言共同协作 70
由于有了上一节的铺垫,本节的内容相对较少,这里给大家准备了两个小文件来实例演示汇编语言和c语言相互调用。会两种不同语言的人,只是掌握了同一件事物的两种表达方式。人在学习一种新语言时,潜意识里是建立了语言符号与事物形象的映射关系,比如我们在学习grape这个单词时,我们之所以认为它就是我们所认知的葡萄,是因为我们知道这两个名词都是在描述同一种圆圆的、黑紫色、甜酸的这一水果的形象,如果脑子中不存在...原创 2019-07-18 18:19:44 · 1419 阅读 · 0 评论 -
一步步编写操作系统 52 深入浅出cpu的特权级
所谓保护模式下的“保护”,主要体现在特权级上,以后随着后面工作的展开,会越来越多的和它们打交道,现在是时候说道说道了。在人类社会中出现恶势力时,人们总是希望出现一位具有神力的英雄来拯救世人、主持公道。阶级是骨子里的东西,它一直存在,然而阶级和平等并不矛盾,阶级是为了平等而生,这是自然界为维护秩序自然产生的事物,如果打破了这个平衡,平等也将不复存在。正因为阶级和平等之间的相互制约,才有了今天的民...转载 2019-07-04 18:42:49 · 350 阅读 · 0 评论 -
一步步编写操作系统 53 任务状态段TSS介绍
操作系统是利用PCB来维护所有任务的,包括进程和线程,但cpu提供的是TSS,linux系统可没用它,因为效率太低。但是还是要了解下TSS才清楚操作系统中某些操作的原因。本节中所讲的特权级与它有着密不可分的联系,TSS作用不止涉及特权级,还包括任务寄存器环境,任务管理相关的内容,为了不干扰大家,这里只介绍和特权级相关的内容,待将来咱们用到更多内容时再和大伙儿细说。TSS,即Task Sta...转载 2019-07-04 18:43:38 · 2254 阅读 · 4 评论 -
一步步编写操作系统 54 CPL和DPL入门1
我们在工作中,公司都给员工配有员工卡,此员工卡就是员工身份的“标签”,用它来出入公司、食堂就餐等。给公司创造价值的是员工的生产力,不是员工卡,员工卡只是公司人事部门管理员工的一种手段而已。现在说计算机,既然是用特权级来维护计算机世界的和平,那总该给每个被管理的对象加个特权“标签”,也就是说cpu得知道谁的特权高谁的特权低,这样才能辨识出是否有低特权级的程序越级访问高特权级资源的违法行为。员...原创 2019-07-05 09:29:20 · 771 阅读 · 0 评论 -
一步步编写操作系统 51 加载内核4
咱们的内容都是连栽的,如果您没看过我之前的文章,本节您是看不懂的。接上节。介绍完内核初始化的函数kernel_init后,本节代码部分还差一点点没说啦,下面看代码:…略179 ;在开启分页后,用gdt新的地址重新加载180 lgdt [gdt_ptr] ; 重新加载181182 ;;;;;;;;;;;;;;;;;;;;;;;;;;;; 此时不刷新流水线也没问题 ;;;;;;;...转载 2019-07-05 09:29:14 · 406 阅读 · 0 评论 -
一步步编写操作系统 48 加载内核1
其实,我们等了这一刻好久好久,即使我不说,大家也有这样的认识,linux内核是用c 语言写的,咱们肯定也要用c语言。其实...说点伤感情的话,今后的工作只是大部分(99%)都要用c语言来写,还有一些要用到汇编的地方。大家也不要因此气馁心灰(其实突然不用汇编还会想它呢,这不是玩笑),我在此过程中一定会尽我所能让内容简单易接受。我们的内核文件是kernel.bin,这个文件是由loader将其从硬...原创 2019-07-05 09:29:07 · 545 阅读 · 0 评论 -
一步步编写操作系统 62 函数调用约定
由于我们要将c语言和汇编语言结合编程啦,所以一定会存在汇编代码和c代码相互调用的问题,有些事情还是要提前交待给大家的,本节就是要给大家说下函数调用规约中的那些事儿。函数调用约定是什么?调用约定,calling conventions,从字面上理解,它是调用函数时的一套约定,是被调用代码的接口,它体现在:参数的传递方式,是放在寄存器中?栈中?还是两者混合; 参数的传递顺序,是从左到右传...原创 2019-07-11 11:12:54 · 247 阅读 · 0 评论 -
一步步编写操作系统 66 浅析c库函数与系统调用1
本来说好的接下来的工作是要去“丰满”我们的内核,可咱们这种一步一回头的学习方式还得继续啊。其实我了解大家急切写内核的心情,但本书《操作系统真象还原》(请大家支持正版)的目的不是写一个操作系统就完事了,而是让大家明白一个至少能运行的操作系统为什么要这样写,所以咱们的学习方式必然是边学习理论知识边实践。如果不给大家交待清楚必要的理论知识,我也对不起自己的良心,我不能为了自己的懒惰而假装大家都明白了。另...转载 2019-07-18 18:14:34 · 228 阅读 · 0 评论 -
一步步编写操作系统 67 系统调用的实现1-2 68
接上文:系统调用的子功能要用eax寄存器来指定,所以咱们要看看有哪些系统调用啦,在linux系统中,系统调用是定义在/usr/include/asm/unistd.h文件中,该文件只是个统一的入口,指向了32位和64位两种版本。在asm目录下提供了这两个版本,文件名分别是unistd_32.h 和unistd_64.h,这里给大家摘录了部分32位x86平台下的unistd_32.h文件,见图...转载 2019-07-18 18:16:47 · 592 阅读 · 0 评论