由0和1组成的机器指令程序员
使用助记符代替机器语言 如:缓存
C\C++\Java\OC\Swift,更加接近人类的天然语言 好比C语言:sass
咱们的代码在终端设备上是这样的过程:安全
汇编语言与机器语言一一对应,每一条机器指令都有与之对应的汇编指令 汇编语言能够经过编译获得机器语言,机器语言能够经过反汇编获得汇编语言 高级语言能够经过编译获得汇编语言 \ 机器语言,但汇编语言\机器语言几乎不可能还原成高级语言markdown
最后来句装13的话架构
越底层越单纯!真正的程序员都须要了解的一门很是重要的语言,汇编!函数
架构 | 设备 |
---|---|
armv6 | iPhone, iPhone2, iPhone3G, 第一代、第二代 iPod Touch |
armv7 | iPhone3GS, iPhone4, iPhone4S,iPad, iPad2, iPad3(The New iPad), iPad mini, iPod Touch 3G, iPod Touch4 |
armv7s | iPhone5, iPhone5C, iPad4(iPad with Retina Display) |
arm64 | iPhone5S 之后 iPhoneX , iPad Air, iPad mini2之后 |
举个例子post
作个小练习性能
答案学习
内存
内存地址空间的大小受CPU地址总线宽度的限制。8086的地址总线宽度为20,能够定位220个不一样的内存单元(内存地址范围0x00000~0xFFFFF),因此8086的内存空间大小为1MB
0x00000~0x9FFFF:主存储器。可读可写
0xA0000~0xBFFFF:向显存中写入数据,这些数据会被显卡输出到显示器。可读可写
0xC0000~0xFFFFF:存储各类硬件\系统信息。只读
学习进制的障碍
不少人学很差进制,缘由是总以十进制为依托去考虑其余进制,须要运算的时候也老是先转换成十进制,这种学习方法是错误的. 咱们为何必定要转换十进制呢?仅仅是由于咱们对十进制最熟悉,因此才转换. 每一种进制都是完美的,想学好进制首先要忘掉十进制,也要忘掉进制间的转换!
进制的定义
作个练习
若是咱们自定义十进制由10个符号组成: 0 1 3 2 8 A B E S 7 逢十进一,这样定义十进制: 1 + 1 = 3!就对了!
这样的目的何在?
传统咱们定义的十进制和自定义的十进制不同.那么这10个符号若是咱们不告诉别人这个符号表,别人是没办法拿到咱们的具体数据的!用于加密!
十进制由十个符号组成,逢十进一,符号是能够自定义的!!
进制的运算
2 + 3 = __ , 2 * 3 = __ ,4 + 5 = __ ,4 * 5 = __.
277 + 333 = __ , 276 * 54 = __ , 237 - 54 = __ , 234 / 4 = __ .
八进制加法表
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 = 10 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
复制代码
实战四则运算
二进制的简写形式
二进制: 1 0 1 1 1 0 1 1 1 1 0 0
三个二进制一组: 101 110 111 100
八进制: 5 6 7 4
四个二进制一组: 1011 1011 1100
十六进制: b b c
复制代码
二进制:从0 写到 1111 0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 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[]) {
printf("%x\n",test());
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
复制代码
那么计算机存储数据它会分为有符号数和无符号数.那么关于这个看图就理解了!
无符号数,直接换算!
有符号数:
正数: 0 1 2 3 4 5 6 7
负数: F E D B C A 9 8
-1 -2 -3 -4 -5 -6 -7 -8
复制代码
自定义进制符号 练习
十进制: 0 1 2 3 4 5 6 7 8 9
自定义: 2 9 1 7 6 5 4 8 3 A
92 99 91 97 96 95 94 98 93 9A
12 19 11 17 16 15 14 18 13 1A
72 79 71 77 76 75 74 78 73 7A
62 69 61 67 66 65 64 68 63 6A
52 59 51 57 56 55 54 58 53 5A
42 49 41 47 46 45 44 48 43 4A
82 89 81 87 86 85 84 88 83 8A
32 39 31 37 36 35 34 38 33 3A
922
复制代码
那么刚才经过10进制运算能够转化10进制而后查表!可是若是是其余进制.咱们就不能转换,要直接学会查表
十进制: 0 1 2 3 4 5 6 7 8
自定义: 2 9 1 7 6 5 4 8 3
92 99 91 97 96 95 94 98 93
12 19 11 17 16 15 14 18 13
72 79 71 77 76 75 74 78 73
62 69 61 67 66 65 64 68 63
52 59 51 57 56 55 54 58 53
42 49 41 47 46 45 44 48 43
82 89 81 87 86 85 84 88 83
32 39 31 37 36 35 34 38 33
922
复制代码
内部部件之间由总线链接
CPU除了有控制器、运算器还有寄存器。其中寄存器的做用就是进行数据的临时存储。
CPU的运算速度是很是快的,为了性能CPU在内部开辟一小块临时存储区域,并在进行运算时先将数据从内存复制到这一小块临时存储区域中,运算时就在这一小快临时存储区域内进行。咱们称这一小块临时存储区域为寄存器。
对于arm64系的CPU来讲, 若是寄存器以x开头则代表的是一个64位的寄存器,若是以w开头则代表是一个32位的寄存器,在系统中没有提供16位和8位的寄存器供访问和使用。其中32位的寄存器是64位寄存器的低32位部分并非独立存在的。
浮点和向量寄存器
由于浮点数的存储以及其运算的特殊性,CPU中专门提供浮点数寄存器来处理浮点数
如今的CPU支持向量运算.(向量运算在图形处理相关的领域用得很是的多)为了支持向量计算系统了也提供了众多的向量寄存器.
通用寄存器
注意: 了解过8086汇编的同窗知道,有一种特殊的寄存器段寄存器:CS,DS,SS,ES四个寄存器来保存这些段的基地址,这个属于Intel架构CPU中.在ARM中并无
pc寄存器(program counter)
高速缓存
iPhoneX上搭载的ARM处理器A11它的1级缓存的容量是64KB,2级缓存的容量8M.
CPU每执行一条指令前都须要从内存中将指令读取到CPU内并执行。而寄存器的运行速度相比内存读写要快不少,为了性能,CPU还集成了一个高速缓存存储区域.当程序在运行时,先将要执行的指令代码以及数据复制到高速缓存中去(由操做系统完成).CPU直接从高速缓存依次读取指令来执行.
bl指令
CPU从何处执行指令是由pc中的内容决定的,咱们能够经过改变pc的内容来控制CPU执行目标指令
ARM64提供了一个mov指令(传送指令),能够用来修改大部分寄存器的值,好比
可是,mov指令不能用于设置pc的值,ARM64没有提供这样的功能
ARM64提供了另外的指令来修改PC的值,这些指令统称为转移指令,最简单的是bl指令
bl指令 -- 练习
如今有两段代码!假设程序先执行A,请写出指令执行顺序.最终寄存器x0的值是多少?
_A:
mov x0,#0xa0
mov x1,#0x00
add x1, x0, #0x14
mov x0,x1
bl _B
mov x0,#0x0
ret
_B:
add x0, x0, #0x10
ret
复制代码
新建Xcode工程命名为汇编01
,新建Empty文件命名为asm.s
在asm.s中写代码
.text
.global _A,_B
_A:
mov x0, #0xa0
mov x1, #0x00
add x1, x0, #0x14
mov x0,x1
bl _B
mov x0, #0x0
ret
_B:
add x0, x0, #0x10
ret
复制代码
咱们能够看到这个文件是会正常参加编译的
在另外一个文件中尝试调用_A
函数
假如没有asm.s
文件的话A()
函数有声明没有实现是不能编译经过的,咱们选择真机尝试编译
选择真机进行编译,注意要用真机!!!!!
咱们发现是能够编译成功的,这就说明asm.s
文件中的_A
函数有效果了
勾选Debug -> always show disassembly
在A()
函数处打断点并运行工程
注意工做台选择All Variables,Registers,Globals and Statics
这时咱们能够查看寄存器信息
按住control
单步执行汇编指令并观察寄存器x0
和x1
的值的变化
例如执行完指令mov x0,#0xa0
以后x0
寄存器的值变为0xa0
可是执行到最后两句指令时咱们发现进入了死循环,这是为何呢???请听下回分解