兰陵月 发表于 2017-10-25 21:14:10

X86汇编语言-从实模式到保护模式—笔记(1)

本帖最后由 兰陵月 于 2017-12-5 21:56 编辑

第1部分预备知识第1章十六进制计数法1.1二进制计数法回顾【1.1.1 关于二进制计数法】在计算机里用高低两种电平的组合来表示数字。一般情况下,高电平表示1,低电平表示0。从数学的角度看,二进制计数法是现代主流计算机的基础。一方面,它简化了硬件设计。因为它只有两个符号,要得到它们,可以用最少的电路元件来接通或者关断电路就行了。另一方面,二进制数与我们熟悉的十进制数之间有着一对一的关系,任何一个十进制数都对应着一个二进制数,不管它有多大。组成二进制数的每一个数位,称为一个比特(bit),而一个二进制数可以看成是一个比特串。很明显,它的数值越大,比特串就越长,这是二进制计数法不好的一面。【1.1.2 二进制到十进制的转换】每一种计数法都有自己的符号(数符)。十进制有0、1、2、3、4、5、6、7、8、9十个符号,二进制只有0、1两个符号。这些数字符号的个数称为基数。也就是说,十进制有10个基数,而二进制只有两个基数。二进制和十进制都是进位计数法。进位记数法的一个特点是,符号的值和它在这个数中所处的位置有关。比如十进制数356,数字6处在个位上,所以是“6个”;5处在十位上,所以是“50”,3处在百位上,所以是“300”。即:百位3、十位5、个位6=3×102+5×101+6×100=356这就是说,由于所处的位置不同,每个数位都有一个不同的放大倍数,这称为“权”。每个数位的权是这样的计算的(这里仅讨论整数):从右往左开始,以基数为底,指数从0开始递增的幂。正如上面的公式所清楚表明的那样,“6”在最右边,所以它的权是以10为底,指数为0的幂100;而3的权是以10为底,指数为2的幂102。数字后面紧跟大写的B,表示这是一个二进制数。紧跟大写的D表示这是一个十进制数。“B”和“D”分别是英语单词Binary和Decimal的头一个字母,这两个单词分别表示二进位和十进位的意思。【1.1.3 十进制到二进制的转换】为了将一个十进制数转换成二进制数,可以采用将它不停地除以二进制的基数2,直到商为0,然后将每一步得到的余数按先后顺序从右至左串起来,就是我们所要转换的二进制数。1.2十六进制计数法【1.2.1 十六进制计数法的原理】二进制的缺点就是写起来太长,不方便。于是,人们发明了十六进制计数法。十六进制有十六个数符,分别是0、1、2、3、4、5、6、7、8、9、A、B、C、D、E、F。前面10个数符和十进制的10个数符是一样的,从A开始到F,分别对应十进制的10、11、12、13、14、15。在十六进制里,一旦某个数位增加到9之后,下一次,它将变成A,而不是直接进位。十六进制计数法是逢十六进位,因此只发生在某个数位原先是F的情况下,比如1F加1之后就变成20。【1.2.2 十六进制到十进制的转换】   将1个十六进制数转换成十进制数的方法同前面,只是在计算权的时候,相应地把幂的底数换为16。比如将十六进制数125转换成十进制数的方法如下:125H=1×162+2×161+5×160=293D数字后面加“H”,表示这是一个十六进制数,H是英语单词Hexadecimal的头一个字母,这个单词的意思是十六进制。【1.2.3 十进制到十六进制的转换】把一个十进制数转换成十六进制数,可以采取不停地除以16,直到商为0,然后每次得到的余数按先后顺序从右至左排列,就得到所要转换的十六进制数。【1.2.4 为什么需要十六进制】4比特的二进制数,可以表示的数是从0000到1111,也就是十进制的0~15,正好对应于十六进制的0~F。如果将一个二进制数从右往左,分成4比特为一组的形式,分别将每一组的值转换成十六进制数,就可以得到这个二进制数所对应的十六进制数。从事计算机的学习和研究,不可避免地要与二进制数打交道,而且有时候还必须针对其中某些比特进行特殊处理。这个时候,如果想保留二进制数的直观性,同时还要求写起来简短,十六进制数是最好的选择。第2章处理器、内存和指令2.1最早的处理器1947年,美国贝尔实验室的肖克利和同事们一起发明了晶体管。1958年,美国人杰克·基尔比发明了集成电路。1971年,在为日本人设计计算器芯片的过程中,受到启发的Intel公司生产了世界上第一个处理器INTEL 4004,设计者为弗德里科·法金。处理器(Processor)是电子计算机的核心,它会在振荡器脉冲的激励下,从内存中获取指令,并发起一系列由该指令所定义的操作。当这些操作结束后,它接着再取下一条指令。通常情况下,这个过程是连续不断、循环往复的。2.2寄存器和算术逻辑部件1byte=8bit    1word=2byte    1 double word=2 word2.3内存储器对于个人计算机来说,内存按字节来组织,单次访问的最小单位是1字节,这是最基本的存储单元。内存中的每一个字节都对应着一个地址。为了访问内存,处理器需要给出一个地址。访问包括读和写。因此在访问的时候,处理器还要指明,本次访问是读访问还是写访问。如果是写访问,则还要给出待写入的数据。尽管内存的最小组成单位是字节,但是,经过精心的设计和安排,它能够按字节、字、双字和四字节进行访问。意思就是说仅通过单次访问就能处理8位、16位、32位或者64位的二进制数。处理器发出字长控制信号,以指示本次访问的字长是8、16、32还是64。2.4指令和指令集设计处理器的目标之一就是使它成为一种可以自动进行操作的器件。同时,处理器的设计者用某些数字来指示处理器所进行的操作,这称为指令,或者叫机器指令。一般来说,指令由操作码和操作数构成,但也有小部分指令仅有操作码,而不含操作数,比如F4H(停机指令)。指令的长度不定,短的指令仅有1字节,而长的指令则有可能达到15字节(对于INTELx86处理器来说)。对处理器来说,指令的操作码隐含了如何执行该指令的信息,比如它是做什么的,以及怎么去做。操作数紧跟在操作码之后,可以立即从指令中取得,所以叫做立即数,立即数已经在指令中给出,不需要再次访问内存。低端字节序,它规定高字节位于高地址部分,低字节位于低地址部分。反之称为高端字节序。指令和数据要分开存放,分别位于内存中的不同区域,存放指令的区域叫代码区,存放数据的区域叫做数据区。一个处理器能够识别的指令的集合,称为该处理器的指令集。2.5古老的Intel8086处理器8086是Intel公司第一款16位处理器,诞生于1978年,所以说它很古老。是整个Intel32位架构处理器(IA-32)的开山鼻祖。【2.5.1 8086的通用寄存器】8086处理器内部有8个16位的通用寄存器,分别是AX、BX、CX、DX、SI、DI、BP、SP。通用的意思是它们之中的大部分都可以根据需要用于多种目的。其中,AX、BX、CX、DX又可以分别分开为8位的寄存器,分别是AH、AL、BH、BL、CH、CL、DH、DL。当一个16位的寄存器当成两个8位的寄存器来用时,对其中一个8位寄存器的操作不会影响到另一个8位寄存器。【2.5.2 程序的重定位难题】为了让程序在内存中的任何位置正确执行,在编写程序时只能使用相对地址或者逻辑地址,而不能使用真实的物理地址。8086处理器用分段机制解决程序重定位问题。【2.5.3 内存分段机制】段可以开始于内存中的任何位置,段内的每一个单元相对段的起始地址有一个相对差,叫做偏移地址。于是,采用分段机制之后,一个内存单元的地址可以采用“段地址:偏移地址”来表示。为了在硬件一级提供对“段地址:偏移地址”内存访问模式的支持,处理器至少要提供两个段寄存器,分别是代码段寄存器CS和数据段寄存器DS。对CS内容的改变将导致处理器从新的代码段开始执行。同样,在开始访问内存中的数据之前,也必须首先设置好DS寄存器,使之指向数据段。最重要的是,当处理器访问内存时,它把指令中指定的内存地址看成是段内的偏移地址,而不是物理地址。这样,一旦处理器遇到一条访问内存的指令,它将把DS中的数据段起始地址和指令中提供的段内偏移相加,来得到访问内存所需要的物理地址。当下一次这个程序执行时,如果代码段和数据段在内存中的位置发生了变化,只要把它们的段地址分别传送到CS和DS,它也能够正确执行。【2.5.4 8086的内存分段机制】8086内部有4个段寄存器,分别是CS、DS、ES、SS。IP是指令指针寄存器,它只和CS一起使用。16位的段地址和16位的偏移地址相加,只能得到16位的物理地址。但是8086处理器提供了20根地址线,可以访问多大1M的内存。因此为了形成20位的地址,8086在形成物理地址时,先将段寄存器的内存左移4位(相当于乘以十六进制的10,或者十进制的16),形成20位的段地址,然后再同16位的偏移地址相加,得到20位的物理地址。因为段寄存器是16位的,在段不重叠的情况下,最多可以将1MB的内存分成65536个段,每个段正好是16个字节。同样在不允许段之间重叠的情况下,每个段的最大长度是64KB,因为偏移地址也是16位的,从0000H到FFFFH。在这种情况下,1MB的内存,最多只能划分成16个段,每段长64KB。程序员的任务是定义段地址并设置处理器的段寄存器,其中最重要的是段地址的选取。段的划分是自由的,它可以起始于任何16字节对齐的位置,也可以是任意长度,只要不超过64KB。同一个物理地址,实际上对应着多个逻辑地址。第3章汇编语言和汇编软件3.1 汇编语言简介为了克服机器指令难以书写和理解的缺点,人们想到可以用一些容易理解和记忆的符号,也就是助记符,来描述指令的功能和操作数的类型,这就产生了汇编语言(Assembly Language)。MOV是传送指令,需要两个操作数,分别是目的操作数和源操作数。它们之间要用逗号隔开。【汇编语言对指令的大小写没有特别的要求。】在很多高级语言中,如果要指示一个数是十六进制数,通常不采用在后面加“H”的做法,而是为它添加一个“0x”前缀。用汇编语言提供的符号书写的文本,叫做汇编语言源程序。但是汇编语言源程序是机器无法识别的,因此要将汇编语言源程序转换成机器指令,这个过程叫做编译。编译肯定还需要一个软件,称为编译器,或编译软件。汇编语言源程序经过编译之后,会生成二进制文件或者可执行文件。3.2NASM编译器【3.2.1 NASM的下载和安装】NASM编译器全称是Netwide Assembler,它是可免费使用的开源软件。【3.2.2 代码的书写和编译过程】【3.2.3 用HexView观察编译后的机器代码】

worklalal 发表于 2017-11-29 16:30:46

终于找到一个也在学汇编的人了{:10_254:}

兰陵月 发表于 2017-11-29 17:18:01

worklalal 发表于 2017-11-29 16:30
终于找到一个也在学汇编的人了

我一直在学,而且我学的很基础,不搞懂绝不前进。
当然,我本身是信息专业的,什么基础之类,什么C之类都学过。
现在重新学习汇编,只是为了更好懂计算机,更好干一些刺激的事情。
页: [1]
查看完整版本: X86汇编语言-从实模式到保护模式—笔记(1)