第一节 X86
与ARM
-
- Intel(英特尔)
- 1.1 简介
- 美国的一家以研发、制造、销售CPU为主的公司
- 世界上第一块CPU在1971年诞生于英特尔:
intel 4004
- 名字由来:
INTegrated ELectronic
(集成电子)
- 1.2 产品
- 1978年 ---->
intel 8086
- 1980年 ---->
intel 80186
- 1982年 ---->
intel 80286
- 1985年 ---->
intel 80386
- 1989年 ---->
intel 80486
- 1993年 ---->
intel Pentium(80586)
- 1978年 ---->
- 1.3 指令集架构
- CPU所有指令的集合,简称指令集
- 1.4
X86
指令集架构- 简称
X86架构
或者X86指令集
- 指的是CPU指令集,并非是CPU硬件结构
- 指的是以8086处理器为鼻祖的一系列指令集,并非是某一款处理器的指令集
X86架构
一直延续到了今天,并非到586就结束了
- 简称
- 1.5 其他
X86
架构的强大并不在于它本身,而在于围绕着它所建立起来的软件生态
AMD
公司的CPU也是X86
架构- 专利的保护期只有20年
-
- ARM
- 2.1 简介
- 英国一家以研发CPU为主的公司
- 全称:
Advanced Risc Machine
- 2.2 ARM指令集架构
- 简称ARM架构或ARM指令集
-
- 区别
- 3.1 类型
X86
:复杂指令集(CISC:Complex Instruction Set Computer)
- ARM:精简指令集
(RISC:Reduced Instruction Set Computer)
- 3.2 主要方向
X86
:高性能- ARM:低功耗
- 3.3 市场
X86
:PC、服务器- ARM:手机、平板
第二节 汇编的诞生
- 10111000 00111111 00000000(机器指令/二进制)
- ---->
B8 3F 00
(十六进制形式) - ---->
MOV AX, 3F
(汇编形式)- 含义:将AX寄存器的值设置为
3F
- 含义:将AX寄存器的值设置为
第三节 编译器
- 语言:机器指令/机器语言 ----> 汇编语言
- 计算机只能识别:机器指令/机器语言
- 编译:汇编语言形式 ----> 机器指令形式
第四节 汇编代码的书写与编译
-
- 使用环境与
IDE
- 推荐在windows 7系统下安装相应的环境
- 此处的环境为
NASM
,IDE
为NASM-IDE
- 先进行
NASM
的安装 - 在文件夹中打开
NASM-IDE
,点击选项---->编译环境设置---->在Asm
编译器路径中选中刚才安装的NASM
,注意要以nasm.exe
结尾,路径设置完成以后在存放NASM-IDE
的文件夹中会看到nasmide
的配置设置,到此即完成安装。
- 先进行
- 使用环境与
-
- 代码的书写与编译
-
行号 汇编地址 机器指令 汇编指令 注释 1 00000000 B83F00
mov ax,0x3f
;注释1 2 00000003 B83F00
mov ax,0x3f
;注释2 3 00000006 B83F00
mov ax,0x3f
;注释3
第五节 HexView
(十六进制查看器)
- 可以打开任意文件,将文件的二进制内容转换为十六进制进行展示。
第六节 寄存器、内存
-
- 8位寄存器
- 8个比特(bit) = 1个字节(byte)
-
- 16位寄存器
- 2个字节(byte) = 1个字(word)
-
- 32位寄存器
- 4个字节(byte) = 2个字(word) = 1个双字(double word)
-
- 内存
-
按照字节来存储数据,读写可以访问的最小单位为1个字节(byte),故字节是内存最基本的存储单元。内存中的位同样有高低之分,高位在左,低位在右。
-
第七节 字节序
- 现代计算机系统一般采用字节作为逻辑寻址单位。当物理单位的长度大于1个字节时,就要区分字节顺序。常见的字节顺序有两种:大(高)端和小(低)端
Big Endian(High-byte first)
和Little Endian(Low-byte first)
。Intel X86
平台采用Little Endian
,而PowerPC
处理器则采用了Big Endian
。 - 低端字节序的存储为从右向左存储,先存低位,再存高位。数据的高字节放在高地址,低字节放在低地址。
- 高端字节序的存储为从左向右存储,先存高位,再存地位。数据的高字节放在高地址,低字节放在低地址。
- 不同的处理器有不同的存储方式,
intel
处理器选用的是低端字节序(小端存储)。
第八节 8086的寄存器
-
- 8个通用寄存器
-
通用寄存器组包括
AX
、BX
、CX
、DX
4个16位寄存器,用以存放16位数据或地址。也可用作8位寄存器。用作8位寄存器时分别记为AH
、AL
、BH
、BL
、CH
、CL
、DH
、DL
。只能存放8位数据,不能存放地址。它们分别是AX
、BX
、CX
、DX
的高八位和低八位。若AX=1234H
,则AH=12H
,AL=34H
。通用寄存器通用性强,对任何指令,它们具有相同的功能。为了缩短指令代码的长度,在8086中,某些通用寄存器用作专门用途。例如,串指令中必须用CX
寄存器作为计数寄存器,存放串的长度,这样在串操作指令中不必给定CX
的寄存器号,缩短了串操作指令代码的长度。- 1.1 数据寄存器
AX(Accumulator Register)
:累加寄存器BX(Base Register)
:基址寄存器CX(Count Register)
:计数寄存器DX(Data Register)
:数据寄存器
- 1.2 变址寄存器
SI(Source Index Register)
:源变址寄存器DI(Destination Index Register)
:目的变址寄存器
- 1.3 指针寄存器
BP(Base Pointer Register)
:基址指针寄存器SP(Stack Pointer Register)
:堆栈寄存器
- 1.1 数据寄存器
-
- 4个段寄存器
-
8086/8088CPU
可直接寻址1MB
的存储器空间,直接寻址需要20位地址码,而所有内部寄存器都是16位的,只能直接寻址6KB
,因此采用分段技术来解决。将1MB
的存储空间分成若干逻辑段,每段最长64KB
,这些逻辑段在整个存储空间中可浮动。CS(Code Segment Register)
:代码段寄存器DS(Data Segment Register)
:数据段寄存器ES(Extra Segment Register)
:附加段寄存器SS(Stack Segment Register)
:堆栈段寄存器
-
- 2个控制寄存器
IP(Instruction Pointer Register)
:指令指针寄存器(在其他品牌的处理器中叫做PC(program counter):程序计数器)。8086/8088CPU
中设置了一个16位指令指针寄存器IP
,用来存放将要执行的下一条指令在现行代码段中的偏移地址。程序运行中,它由BIU
自动修改,使IP
始终指向下一条将要执行的指令的地址,因此它是用来控制指令序列的执行流程的,是一个重要的寄存器。8086程序不能直接访问IP
,但可以通过某些指令修改IP
的内容。例如,当遇到中断指令或调用子程序指令时,8086自动调整IP
的内容,将IP
中下一条将要执行的指令地址偏移量人栈保护,待中断程序执行完毕或子程序返回时,可将保护的内容从堆栈中弹出到IP
,使主程序继续运行。在跳转指令时,则将新的跳转目标地址送入IP
,改变它的内容,实现了程序的转移。PSW(Processor Status World Register)
:程序状态字寄存器,也称(FLAG Registor
:标志寄存器)。FR
是16位寄存器,其中有9位有效位用来存放状态标志和控制标志。状态标志共6位,CF
、PF
、AF
、ZF
、SF
和OF
,用于寄存程序运行的状态信息,这些标志往往用作后续指令判断的依据。控制标志有3位,IF
、DF
和TF
,用于控制CPU的操作,是人为设置的。- 0:
CF(Carry Flag)
– 进位标志位 – 运算时最高位产生进位(或借位)时:CF
= 1 - 2:
PF(Parity Flag)
– 奇偶标志位 – 运算结果的低8位中1的数量为偶数时:PF
= 1 - 4:
AF(Auxiliary Carry Flag)
– 辅助进位标志位 – 运算时低4位向高4位产生进位(或借位)时:AF
= 1 - 6:
ZF(Zero Flag)
– 零标志位 – 运算结果为零时:ZF
= 1 - 7:
SF(Sign Flag)
– 符号标志位 –SF
= 运算结果最高位的值 - 8:
TF(Trap Flag)
– 跟踪标志位- –
TF
= 1时,CPU处于单步状态,每执行一条指令自动产生一次内部中断 - –
TF
= 0时,CPU恢复正常
- –
- 9:
IF(Interrupt Flag)
– 中断允许标志位- –
IF
= 1时,处理器可以响应外部中断 - –
IF
= 0时,处理器不响应外部中断
- –
- 10:
DF(Direction Flag)
– 方向标志位- –
DF
= 1时,处理器以递减的顺序处理字符串,地址从高到低递减 - –
DF
= 0时,处理器以递增的顺序处理字符串,地址从低到高递增
- –
- 11:
OF(Overflow Flag)
– 溢出标志位 – 运算时产生溢出:OF
= 1 - 注:8、9、10这三个标志位用来控制CPU的状态,它们的值由指令进行设置,其他标志位的值根据当前的情况自动的刷新。
- 0:
第九节 指令的加载
-
机器指令是由操作码和操作数组成的
-
B8
为操作码,0102
、0506
都为操作数- 正常情况下(高端字节序)操作码的顺序为从左向右依次加载,表示为:
-
1 00000000 B80102 mov ax, 0x0102 2 00000003 B80506 mov ax, 0x0506
-
操作码决定了指令所要做的事情(或者决定了处理器将对操作数执行什么样的操作)
- Intel处理器为低端字节序,故加载顺序时从右侧开始,所以表示为:
-
1 00000000 B80201 mov ax, 0x0102 2 00000003 B80605 mov ax, 0x0506
-
第十节 代码段和数据段
-
10.1 代码段
- 程序员在写程序时要把存储器划分成段,代码段用来存放程序的指令序列,代码段的段地址存放在CS(代码段寄存器)中,
IP
(指令指针寄存器)指示代码段中指令的偏移地址,处理器利用CS:IP
取得下一条要执行的指令。
- 程序员在写程序时要把存储器划分成段,代码段用来存放程序的指令序列,代码段的段地址存放在CS(代码段寄存器)中,
-
10.2 数据段
- 数据段存放当前运行程序所用的数据,数据段的段地址存放在
DS
(数据段寄存器)中。
- 数据段存放当前运行程序所用的数据,数据段的段地址存放在
-
10.3 附加段
- 附加段是附加的数据段,也用于数据的保存,另外,串操作指令将附加段作为其目的操作数的存放区域。附加段的短地址存放在
ES
(附加段寄存器)中。
- 附加段是附加的数据段,也用于数据的保存,另外,串操作指令将附加段作为其目的操作数的存放区域。附加段的短地址存放在
-
10.4 堆栈段
- 堆栈段是堆栈所在的主存区域,堆栈段的段地址存放在
SS
(堆栈段寄存器)中,SP
(堆栈指针寄存器)指示堆栈栈顶的偏移地址,处理器利用SS:SP
操作堆栈中的数据。
- 堆栈段是堆栈所在的主存区域,堆栈段的段地址存放在
-
-
注:用[ ]括起的数据表示为内存地址!
mov ax, [0x0100]
(A1
为操作码,00
、01
为操作数) 将地址为01
、00
的内存单元中的数据传输到AX
寄存器中,操作的字长为两个字节(00
、05
),此时AX
寄存器中的数据变为00
、05
- 注:
intel
处理器为低端字节序,故00
为高字节,05
为低字节。
- 注:
add ax, [0x0102]
(03
、06
为操作码,02
、01
为操作数) 将AX
寄存器中的数据和内存地址为01
、02
的存储单元中的数据进行相加,并将结果存储在AX
寄存器中,操作的字长仍然为两个字节(00
、01
),此时AX
寄存器中的数据变为00
、06
。
-
对于
intel
处理器来说,指令的长度是不确定的,短的指令只有一个字节(停机指令F4
),长的指令可以达到15个字节。
第十一节 程序的重定位难题
-
操作系统决定程序最终会被加载到内存的什么地方,操作系统会根据内存目前的使用情况来为程序分配内存。
- 绝对地址:主存储器的存储单元以字节为编址单位,每个存储单元都有一个地址与其对应。主存空间的地址编号称为主存储器的绝对地址,而与绝对地址对应的主存空间称为物理地址空间。
- 相对地址:在有地址变换功能的计算机中,访问指令给出的地址(操作数)叫逻辑地址,也叫相对地址。需要经过寻址方式的计算或变换才得到内存储器中的物理地址。
-
第十二节 内存分段机制
- 将内存比作一张纸条,可以从任意一段剪下,也就是说内存分段可以从内存的任意位置开始。
- 将内存分段以后,内存除了拥有物理地址,还拥有了逻辑地址,
逻辑地址 = 段地址 + 偏移地址
- 段地址:段的起始地址
- 偏移地址:存储单元相对于段开始位置的距离
- 数据段寄存器
DS
:用于存储数据段的段地址
-
在实际中,处理器会将指令中指定的内存地址看作偏移地址,当处理器执行指令时,会将数据段寄存器
DS
中的段地址和指令中所存储的偏移地址相加,得到逻辑地址,逻辑地址即数据所在的实际地址。 -
-
程序的重定位:虽然程序会被加载到内存中的不同位置,但是我们仍然可以通过逻辑地址来精确的定位到我们想要的数据。
-
指令中的地址是数据在段内的偏移地址
-
数据段寄存器
DS
中的值是数据段的段地址 -
段地址 + 偏移地址 = 逻辑地址
,也就是数据实际所在的位置 -
重定位就是通过改变数据段寄存器
DS
中的值来实现的
第十三节 处理器听谁的指挥
-
数据段寄存器(DS)
和附加段寄存器(ES)
-
若不进行说明,会默认使用
DS
寄存器作为段地址 -
mov ax, [0001]:默认使用DS寄存器作为段地址,0001作为数据在段内的偏移地址 mov ax, [DS:0001]:指定DS寄存器作为段地址,0001作为数据在段内的偏移地址 mov ax, [ES:0001]:指定ES寄存器作为段地址,0001作为数据在段内的偏移地址
-
代码段寄存器(CS)
和指令指针寄存器(IP)
-
CS
:用于存储代码段的起始地址,也就是代码段的段地址 -
IP
:用于存储代码在段内的偏移地址 -
处理器将当前的
CS
和IP
相加,得到指令的逻辑地址,即指令所在的实际地址。同时,处理器会自动的根据当前指令的长度,改变IP
的值,使得IP
指向下一条指令的偏移地址,此时处理器会根据指令的长度来自动的改变偏移地址的值,并指向下一条指令 -
CS
和IP
决定了处理器执行哪条指令
第十四节 8086的内存分段地址
-
8086处理器为16位处理器,正常来讲有16位段地址,16位偏移地址以及16位逻辑地址,但是8086处理器提供了20根地址引线,也就意味着可以访问的最大地址是20位。
-
8086处理器地址引线:20根
-
逻辑地址:20位
-
段地址:20位(左移四位得到:每个分段必须加载到地址最低位<=0>的位置)
-
偏移地址:16位(每个段最大的长度=65536个字节)
偏移地址的值,并指向下一条指令CS
和IP
决定了处理器执行哪条指令