3 songly_

尚未进行身份认证

调试的错误就是编程给你最好的东西,因为在每个错误上面都标志着前进的一步

等级
博文 287
排名 1w+

26-代码跨段跳转

1.什么是代码跨段简单来讲,代码跨段本质上就是修改CS段寄存器的值,即把另一个代码段的描述符加载到cs段寄存器。前面我们也说过,CS段寄存器不能单独修改,需要和EIP寄存器一起修改才行,因此想要实现代码跨段访问就需要使用一些特定的指令来完成,例如jmpfar指令就可以完成代码跨段访问。2.代码间跳转流程2.1查表得到段描述符然后CPU根据段选择子查找G...

2019-06-15 19:34:24

25-段权限检查

1.CPU分级保护模式下的CPU分成了4个级别,通常称为0环,1环,2环,3环。处在最中间的0环是CPU运行特权指令的,0环的特权级别最高,通常我们所写的内核程序,驱动程序就运行在0环。基于操作系统写的用户程序则运行在3环,同理,3环的特权级别最低(为了方便理解,你可以把0环理解为内核程序运行的内核空间,3环是用户程序运行的用户空间)。需要明白的一点是,所谓0环也好,3环也好,都是对...

2019-06-11 00:05:56

24-段描述符属性

1.段描述符属性S位S位用于指定描述符的类型,当S=0表示是一个系统段,S=1则表示是一个数据段或代码段,对于系统段我们将在后面介绍。2.段描述符属性Type域Type字段有4位,用于指定描述符的子类型。对于Type来说,当S=1或0时,Type所表示的含义是完全不一样的,这里我们只讨论S=1的情况。对于数据段来说,Type有E,W,A三位;对于代码段来说,Type有C,...

2019-06-08 21:25:41

23-段描述符与段选择子

1.GDT表现在思考一个问题,当你写一个段寄存器的时候,只给了一个16位的数,但段寄存器有96位,那剩下的80位是怎么来的?这个16位的数是随便写的吗?通常在执行MOVDS,AX这些指令时,CPU会查表,并根据AX的值来决定查找GDT还是LDT(局部描述符表),查找表的什么位置,查出多少数据。有同学可能会好奇GDT表在哪里,表的大小有多大呢?这就要说到gdtr寄存器了,gdtr是一个4...

2019-06-08 13:12:03

22-从段寄存器开始

1.ds寄存器保护模式有2种非常重要的机制:段和页,这2种机制都是非常复杂的,无论是学习段或者页的机制,在此之前都要先了解段寄存器。来看下面这一段代码:movdwordptrds:[0x123456],eax在上面的代码中,有一个ds寄存器,根据前面学习实模式我们知道ds是一个数据段寄存器。eax是一个32位的寄存器,dword表示4字节,正好也是32位。换句话说,这段代...

2019-06-08 12:33:53

21-32位处理器架构

在前面的学习中,8086CPU是基于16位的实模式,并且有20根地址线,寻址范围为1MB内存;32位的处理器架构是延续8086发展而来的,对8086有很好的兼容性。相信学过计算机的同学都知道,32位系统最大只识别4G内存,原因在于32位的处理器有32根地址总线,寻址长度为4G内存。另外,16位处理器的通用寄存器有8个,即AX、BX、CX、DX、SI、DI、BP和SP;而...

2019-05-29 22:56:55

20-8086处理器的中断机制

中断就是打断处理器当前的执行流程,去执行另外一些和当前工作不相干的指令,执行完以后,还可以返回到原来的程序流程继续执行。在现实生活中我们也会经常遇到类似中断这样的事情,例如你正在用手机听歌,突然你的电话响了,这时处理器必须中断歌曲的播放,来处理这件更为重要的事件。中断可以分为两大类:CPU内部中断和CPU外部中断。1.外部硬件中断从字面意思理解,外部硬件中断就是处理器外面...

2019-04-03 17:47:26

21-非阻塞accept

1.回忆accept函数之前在10-在accept之前中止连接(连接异常)这一篇中已经讨论过在accept之前中止连接的情况了,不过从最终的结果来看,accept并没有返回错误,而是之后调用read读取已连接套接字时产生了错误。另外,当一个已完成连接正等待被服务端accept时,select会把该连接的套接字作为读描述符并返回。这意味着之后的accept就不应该阻塞,但是会引发一个...

2019-01-07 14:58:41

20-unix域套接字地址结构

1.unix域协议看到这个标题,不知道的小伙伴肯定以为这是一个协议族之类的,但实际上unix域协议是在单台主机上客户端与服务端之间的通信方法,简单来说,unix域协议也是一种进程间通信方式,用于同一台主机上的客户端和服务端,为不同的进程间传递描述符。通常在同一台主机上,使用unix域套接字通常比TCP套接字效率更高,同时unix域套接字还可以用于在进程间传递描述符等等。那么unix域...

2019-01-05 14:00:25

19-高级I/O函数——套接字和标准I/O

之前我们一直使用的read,write函数以及它们的变体recv,send等函数执行I/O,这些函数都是要使用描述符的,通常这些函数都作为unix内核中的系统调用实现。除了以上说的系统调用,我们也可以使用标准I/O函数库(standardI/Olibary),这个函数库由ANSIC标准进行规范,不过使用标准I/O函数需要创建一个标准I/O流,我们可以使用fdopen函数来完成,...

2019-01-04 17:44:41

19-再谈8086CPU的分段机制

前面已经简单的讨论过8086CPU的分段机制了,如果已经忘了的同学赶快回去复习一遍(传送门:3-浅谈8086CPU的内存分段机制),在这一篇我们将针对前面的知识进行补充和应用。8086处理器的工作模式是逻辑上对内存分成各个段(程序员自己抽象),8086处理器在执行指令处理数据时,例如获取下一条指令或者获取某个数据信息,肯定会涉及到寻址,而在8086中一律按照“段地址x16+偏移地址”的...

2019-01-01 12:33:34

汇编语言修炼目录

参考资料:《x86汇编语言:从实模式到保护模式》《汇编语言》预备知识1-计算机和汇编语言2-8086CPU给出的物理地址方法3-浅谈8086CPU的内存分段机制4-计算机的启动过程5-安装虚拟机和NASM汇编器16位实模式6-如何显示文字和图像7-第一个汇编程序helloworld8-div指令和进制转换9-常用的汇编指令10-x86...

2019-01-01 10:53:22

18-子程序调用

1.接口封装下面这个汇编程序是实现三数求和的功能:movax,0x0000movss,axmovsp,0xFFFFmovbp,0xFFFF;计算100+200+300push100push200push300movax,word[ss:bp-2];把第一个数加数放到ax中。addax,word[ss:bp-4];把第一个数和第二个数相加,...

2018-12-28 20:34:40

17-equ伪指令和jmp指令

1.equ指令equ指令(英文为:equal),在Nasm汇编器中是一条伪指令。我们知道伪指令不能直接执行,需要经过编译器处理转换成纯汇编指令。类似equ指令的语法,在很多编程语言中都存在,有的叫做定义常量,比如我们学习C语言会接触到一个#define的语法,跟equ指令的作用是一样的,因为equ指令的本质就是替换。 直接上代码吧:movax,100movbx,100m...

2018-12-27 09:56:58

16-8086处理器的寻址方式

CPU作为计算机的中央处理器,每天忙忙碌碌,只要它工作着就会不断地运行指令,处理各种数据。既然要处理数据,就会涉及两个问题:1.数据在哪里,如何获取2.处理完之后,把数据送到哪里去而在计算机中,寻址方式就是如何找到要操作的数据,以及把数据处理完存放到哪里。对于8086处理器来说,它的寻址方式大致分为这几类:寄存器寻址,立即寻址,内存寻址,下面我们分别来讨论这几种寻址方式。 ...

2018-12-25 17:13:41

15-栈和栈的初始化

计算机工程师们为了设计出更高效,更易于控制管理的程序,把内存分成一些不同的区域(详细见4-计算机的启动过程中的图3),其中有一块区域就是“栈”,本质上栈是一段内存空间,在计算机里领域里代表:数据临时存储的地方。同时栈也是一种数据存储结构,这对于学过数据结构这门课的同学来说并不难理解,我们知道“栈”在程序设计中是经常使用的,在早期,设计8086处理器的计算机工程师为了更方便的管理“栈”这段内存,...

2018-12-24 16:11:44

14-movesb指令和movesw指令

1.movesb指令movsb可以理解为 movestringbyte,即字节传送指令。 来看一个示例,汇编代码如下:movax,0x0050moves,axmovax,0x07C0movds,axjmpnearCode;把这5个数据复制到起始地址0x00500的位置Data:db0xAA,0x11,0x22,0x33,0x44Cod...

2018-12-23 14:30:08

13-ZF标志位,JB和JNB跳转指令

1.ZF标志位这一节我们将来学习一下标志寄存器的ZF(ZeroFlag)零标志位。对于ZF标志位,当运算结果为0的时候,那么ZF=1,当运算结果不为0的时候,ZF=0。 例如下面这段汇编指令:movax,10movdx,10subax,dx但sub指令一旦运行,就会修改寄存器里面的值,当ax和dx进行减法运算的结果为0时,那么ZF标志位就会被置为1。有些...

2018-12-22 16:36:33

12-数据宽度

现在有一个十进制数字123,如果我们希望用4位数来表示这个数字可以写成0123,如果用7位数来表示可以写成0000123。同理,对于负数-233,用5位数来表示就是-00233。乍一看用这种方式来表示数字好像也没啥意义,前面我们学习的寄存器都是8位或16位的,但是,如今的大多数CPU都使用了64位寄存器。我们知道一个十进制数字15D以有符号数格式存放在8位寄存器al中,用二进制来表示...

2018-12-19 16:00:35

11-有符号数和无符号数

1.有符号数和无符号数无符号数,因为没有符号位,所以只能表示一个正数。有符号数,因为存在符号位,符号位如果是0的话,代表这是一个正数,符号位如果是1的话,代表这个数是一个负数。 我们可以用db伪指令来声明一些数字: 编译之后:10D的十六进制表示就是0x0A,11D的十六进制表示就是0x0B,17D的十六进制表示就是0x11 但自从学习汇编语言,我们还...

2018-12-18 18:24:41
奖章
  • 专栏达人
    专栏达人
    授予成功创建个人博客专栏的用户。专栏中添加五篇以上博文即可点亮!撰写博客专栏浓缩技术精华,专栏达人就是你!
  • 持之以恒
    持之以恒
    授予每个自然月内发布4篇或4篇以上原创或翻译IT博文的用户。不积跬步无以至千里,不积小流无以成江海,程序人生的精彩需要坚持不懈地积累!
  • 勤写标兵Lv1
    勤写标兵Lv1
    授予每个自然周发布1篇到3篇原创IT博文的用户。本勋章将于次周上午根据用户上周的博文发布情况由系统自动颁发。