鱼C论坛

 找回密码
 立即注册
查看: 2687|回复: 2

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

[复制链接]
发表于 2017-10-25 21:14:10 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 兰陵月 于 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的头一个字母,这两个单词分别表示二进位和十进位的意思。[20170912]
【1.1.3 十进制到二进制的转换】
为了将一个十进制数转换成二进制数,可以采用将它不停地除以二进制的基数2,直到商为0,然后将每一步得到的余数按先后顺序从右至左串起来,就是我们所要转换的二进制数。[20170913]
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,然后每次得到的余数按先后顺序从右至左排列,就得到所要转换的十六进制数。[20170917]
【1.2.4 为什么需要十六进制】
4比特的二进制数,可以表示的数是从0000到1111,也就是十进制的0~15,正好对应于十六进制的0~F。
如果将一个二进制数从右往左,分成4比特为一组的形式,分别将每一组的值转换成十六进制数,就可以得到这个二进制数所对应的十六进制数。
从事计算机的学习和研究,不可避免地要与二进制数打交道,而且有时候还必须针对其中某些比特进行特殊处理。这个时候,如果想保留二进制数的直观性,同时还要求写起来简短,十六进制数是最好的选择。[20170924]
第2章  处理器、内存和指令
2.1  最早的处理器
1947年,美国贝尔实验室的肖克利和同事们一起发明了晶体管。1958年,美国人杰克·基尔比发明了集成电路。1971年,在为日本人设计计算器芯片的过程中,受到启发的Intel公司生产了世界上第一个处理器INTEL 4004,设计者为弗德里科·法金。
处理器(Processor)是电子计算机的核心,它会在振荡器脉冲的激励下,从内存中获取指令,并发起一系列由该指令所定义的操作。当这些操作结束后,它接着再取下一条指令。通常情况下,这个过程是连续不断、循环往复的。
2.2  寄存器和算术逻辑部件
1byte=8bit    1word=2byte    1 double word=2 word
2.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.2  NASM编译器
【3.2.1 NASM的下载和安装】
NASM编译器全称是Netwide Assembler,它是可免费使用的开源软件。
【3.2.2 代码的书写和编译过程】
3.2.3 HexView观察编译后的机器代码】

本帖被以下淘专辑推荐:

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2017-11-29 16:30:46 | 显示全部楼层
终于找到一个也在学汇编的人了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-11-29 17:18:01 | 显示全部楼层
worklalal 发表于 2017-11-29 16:30
终于找到一个也在学汇编的人了

我一直在学,而且我学的很基础,不搞懂绝不前进。
当然,我本身是信息专业的,什么基础之类,什么C之类都学过。
现在重新学习汇编,只是为了更好懂计算机,更好干一些刺激的事情。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-24 23:06

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表