01-汇编

2021-03-24  本文已影响0人  BBLv

汇编语言的发展

机器语言

由0和1组成的机器指令(本质上就是有电和没电)

在早期变成过程中,由于使用机器码这种方式很难受,慢慢的衍生除了助记符,如:

汇编语言(assembly language)

助记符这种方式很大程度的方便了编写代码,逐渐就形成了汇编语言,换句话说,汇编语言可以是助记符的集合(纯个人胡说。。。),汇编语言的特点是用符号代替了机器代码指令,而且与机器代码有一一对应的关系:

高级语言(High-level programming language)

比如C、C++、Objective-C、swift,更符合,更能让人理解的语言,对于iOS来讲,Objective-C向swift转变是一个必然的过程,在接触swift的过程中,我发现swift与Android的Kotlin,Python,Java等等这些语言有了一些共通的地方,使得不同专业的同学对于跨专业操作编的更加的容易,我有一个疑问,在不久的未来,AI可以商用,甚至民用、通用,语言会不会大一统呢(这里也是个人胡说。。。)
回到高级语言,特点是通用性强,缺点也很明显,体积更大。

代码在终端上的编译过程:


15193669666308.jpg

汇编语言的特点

汇编语言的用途:(见仁见智)

借用大佬的话:

越底层越单纯、汇编是程序员需要用心理解的一门语言(串改了)

汇编的种类:

架构 设备
armv6 iPhone、iPhone2、iPhone3G、第一代、第二代iPod Touch
armv7 iPhone3GS、iPhone4S、iPad、iPad2、IPad3(The New iPad)、iPad mini、IPad Touch3G、iPod Touch4
armv7s iPhone5、iPhone5C、iPad4(iPad withRetina Display)
arm64 iPhone5S--iPhoneX,iPad Air,iPad mini2---

必备知识:

CPU

15193693448725.jpg

总线:

CPU与内存的桥梁:是一根根导线的集合。每个cpu有很多针脚,通过这些针脚与外部链接,与外部交互。

总线的分类:

地址总线:功能是寻址,总线的宽度决定了寻址能力,每根导线可以表示(0和1),CPU跟内存是有关系滴,在早期的时候如果内存过大,CPU的寻址能力不够,内存访问不到。但是也有解决方案,CPU进行两次寻址,然后相加,但是这样的方式就注定了速度变慢。现在CPU寻址能力是饱和的,64位cpu。8086的地址总线宽度是20根,所以寻址能力是1M(2^20)

控制总线:它的宽度决定了CPU对其他控件的控制能力,能有多少控制

数据总线 :它的宽度决定了CPU的单次数据传送量,也就是数据传送速度,或者可以描述为CPU的吞吐量

通常讲32位CPU、64位CPU指的是CPU的数据总线宽度。对于一个引用数据对象,在编程过程中,一个指针8占用字节,一次放电就可以搞定(64位)

8086CPU数据总线宽度是16,单次传输数据2字节
32位CPU一次放电可以传递4字节
64位CPU一次放电可以传递8字节

CPU是如何工作的:
2990730-bfac743167c4e554.png

此图演示的是CPU从内存3号单元读取数据:

  1. cpu通过地址总线将3传输给内存(我将要访问地址3)
  2. cpu通过控制总线将命令传输给内存(我将要读/写操作)
  3. cpu通过数据总线如果是读操作:那么内存将3内的数据通过数据总线传输给CPU,如果是写操作,CPU将数据传递给内存3

App的加载流程:

15193672391363.jpg

App通过编译最后生成的Mach-o(二进制文件)文件要存放在本地磁盘中(硬盘),知道要运行的时候回将App加载进内存,这个时候叫Image(镜像文件),然后通过CPU对内存的读/写操作,通过控制指令对终端设备中的各个模块进行控制。

二进制文件与镜像文件的区别是什么?
在早期来讲是一样的,只是copy了一份放在了内存中,镜像是早期遗留下来的说法,方便CPU的使用。现在来讲区别我还不清楚,学习过之后进行补充

内存

2990730-d723c11cce5cdaaf.png

此图是8086CPU的内存空间:8086CPU的地址总线宽度为20,可以定位到2^20个不同的内存单元(内存地址的范围是0x00000-0xFFFFFF),所以8086的内存空间大小为1M。

这个作为早期的内存结构,现在的内存是访问不到系统信息的,因为做了虚拟地址的隔离

进制

学习进制的障碍

进制学习的主要障碍是我们的教育目前都是以十进制来传递给我们的,学习使用了很多年,已经深入骨髓,在学习其他进制的时候,总是要以十进制为依托,先入为主,器思考,这种方式本质上就是错误的。现在程序员接触到的二进制、八进制、十六进制,每一种进制都是完美的。都有各自的计算规则。不需要按十进制来思考!不需要按十进制来思考!不需要按十进制来思考!重要的事情讲三遍。

进制的定义

其实我们国家古代的人是非常智慧的,十六进制使用的是非常早的,“半斤八两”讲的就是十六进制。一斤是16两

进制的运算

八进制加法表
 0   1   2   3   4   5   6   7
10  11  12  13  14  15  16  17
20  21  22  23  24  25  26  27
. . .

1+1 = 2
1+2 = 3  2+2 = 4
1+3 = 4  2+3 = 5   3+3 = 6
1+4 = 5  2+4 = 6   3+4 = 7   4+4 = 10
1+5 = 6  2+5 = 7   3+5 = 10  4+5 = 11  5+5 = 12
1+6 = 7  2+6 = 10  3+6 = 11  4+6 = 12  5+6 = 13  6+6 = 14
1+7 = 8  2+7 = 11  3+7 = 12  4+7 = 13  5+7 = 14  6+7 = 15  7+7 = 16
. . .
八进制乘法表
 0   1   2   3   4   5   6   7
10  11  12  13  14  15  16  17
20  21  22  23  24  25  26  27
. . .

1*1 = 1
1*2 = 2  2*2 = 4
1*3 = 3  2*3 = 6 3*3 = 11
1*4 = 4  2*4 = 10 3*4 = 14  4*4 = 20
1*5 = 5  2*5 = 12  3*5 = 17  4*5 = 24  5*5 = 31
1*6 = 6  2*6 = 14  3*6  = 22  4*6 = 30  5*6 = 36  6*6 = 44
1*7 = 7  2*7 = 16  3*7 = 25  4*7 = 34  5*7 = 43  6*7 = 52  7*7 = 61
. . .   

二进制:从0写到1111
0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1111
十六进制:
0 1 2 3 4 5 6 7 8 9 A B C D E F

数据宽度

数学上的数字,是没有大小限制的,可以无限大,但是在计算机中,由于受硬件的制约,数据都是有长度限制的(成为数据宽度),超过最大数据宽度的数据会被丢弃

#import <UIKit/UIKit.h>
#import "AppDelegate.h"


int test() {
    int cTemp = 0x1FFFFFFFF;
    return cTemp;
}

int main(int argc, char * argv[]) {
    NSString * appDelegateClassName;
    
    printf("cTemp:%x\n",test());
    
    @autoreleasepool {
        // Setup code that might create autoreleased objects goes here.
        appDelegateClassName = NSStringFromClass([AppDelegate class]);
    }
    return UIApplicationMain(argc, argv, nil, appDelegateClassName);
}

会有一个警告

Implicit conversion from 'long' to 'int' changes value from 8589934591 to -1,cTemp的值为-1

计算机中常见的数据宽度

计算机储存数据会分为有符号和无符号数,无符号数,直接运算。有符号数:正数:0 - 7,负数:-8 - F,


15178439312380.jpg

CPU&寄存器

内部部件之间由总线连接

15193738988252.jpg

CPU包含控制器运算器寄存器,其中寄存器的作用就是用来临时数据的存储。

CPU的运算速度是非常快的,为了性能CPU在内部开辟了一小块临时存储区域,并在进行运算时,先将数据从内存复制到这一小块临时存储区域中,运算时就在这一小块存储区域进行。我们称这一小块临时存储区域为寄存器。

对于arm64的CPU来讲,如果寄存器以“x”开头,则表明是一个64位寄存器,如果以“w”开头则表明是一个32位寄存器,在系统中没有提供16位和8位的寄存器提供访问和使用。其中32位寄存器是64位寄存器的低32位部分,并不是独立存在的。

浮点寄存器

因为浮点数的存储以及其运算的特殊性,CPU中专门提供浮点寄存器来处理浮点数

截屏2021-03-25 19.09.57.png

向量寄存器

现在的CPU支持向量运算(向量运算在图形处理相关领域使用的非常的多),为了支持向量运算计算机系统也提供了众多的向量寄存器

截屏2021-03-25 19.10.35.png

通用寄存器

截屏2021-03-25 19.10.53.png 截屏2021-03-25 19.11.03.png

注意:
对于8086CPU,有一种特殊的寄存器,CS、DS、SS、ES四个寄存器来保存这些段的及地址,这个是属于Intel架构的CPU,ARM中并没有

使用流程:
通常,CPU会先将内存中的数据储存到寄存器中,然后在对通用寄存器中的数据进行运算。
假设内存有红色内存空间的值是3,现在想把他+1,并将结果存储在蓝色空间内:

15193703231861.jpg

pc寄存器

指令指针寄存器,它指示了CPU当前要读取指令的地址
在内存或者磁盘上,指令和数据没有任何区别,都是二进制信息

cpu在工作的时候吧有的信息当做指令,有的信息看做数据,为同样的信息赋予了不同的意义
比如:1110 0000 0000 0011 0000 1000 1010 1010,可以当做数据0xE003008AA,也可以当做指令mov x0,x8

cpu根据什么将内存中的信息当做指令处理
CPU将PC寄存器只想的内存单元的内容看做指令
如果内存中的某段内容曾被CPU执行过,那么它所在的内存单元一定被CPU指向过

高速缓存

iPhoneX上搭载的ARM处理器A11它的1级缓存的容量是64KB,2级缓存的容量是8M

CPU每执行一条指令前都需要从内存中将指令读取到CPU内并执行。而寄存器的运行速度相比内存读写要快的多,为了性能,CPU还集成了一个高速缓存区域,当程序运行时,先将要执行的指令代码以及数据复制到高速缓存中区(由系统完成),CPU直接从高速缓存依次读取指令来执行

b指令与bl指令

其他

数量单位:(1M=1024K 1K=1024)

容量单位:(byte)(1024B = 1KB 1024KB = 1MB)

带宽(100M):是指100Mbps,传输速率的单位,每秒钟传输多少个二进制位,bit位,100M带宽理论上的下载速度是12.5M

上一篇下一篇

猜你喜欢

热点阅读