引言
什么是汇编语言?
答:汇编语言是计算机语言,通俗来讲就是人类与计算机(CPU)交流的桥梁,计算机不认识人类的语言,想要让计算机去完成人们的工作,就需要俺们将这些工作翻译成计算机语言,属于低级计算机语言。
APP与汇编语言的关系
一个APP安装到操作系统上面的可执行的文件本质上来讲就是二进制文件,操作系统本质上执行的指令也是二进制,是由CPU执行的;
汇编语言的发展
机器语言(Machine language)
由0
和1
组成的机器指令
如:
* 加:0100 0000
* 减:0100 1000
* 乘:1111 0111 1110 0000
* 除:1111 0111 1111 0000
汇编语言(assembly language)
使用助记符代替机器语言
如:
- 加:INC EAX 通过编译器 0100 0000
- 减:DEC EAX 通过编译器 0100 1000
- 乘:MUL EAX 通过编译器 1111 0111 1110 0000
- 除:DIV EAX 通过编译器 1111 0111 1111 0000
高级语言(High-level programming language)
注意:上述指令,CPU读的懂
C\C++\Java\OC\Swift,更加接近人类的自然语言
比如C语言:
- 加:A+B 通过编译器 0100 0000
- 减:A-B 通过编译器 0100 1000
- 乘:A*B 通过编译器 1111 0111 1110 0000
- 除:A/B 通过编译器 1111 0111 1111 0000
代码在设备上执行的过程是这样的:
- 汇编语言与机器语言一一对应,每一条机器指令都有与之对应的汇编指令
- 汇编语言可以通过编译得到机器语言,机器语言可以通过返汇编得到汇编语言
- 高级语言可以通过编译得到汇编语言\机器语言,但机器语言几乎不可能还原成高级语言
汇编语言的特点
- 可以直接访问、控制各种硬件设备,比如存储器、CPU、内存等,能最大限度地发挥硬件的功能
- 能够不受编译器的限制,对生成的二进制代码进行完全的控制
- 目标代码简短,占用内存少,执行速度快
- 汇编指令是机器指令的助记符,同机器指令--对应。每一种CPU都有自己的机器指令集\汇编指令集,所以汇编语言不具备可移植性
- 知识点过多,开发者需要对CPU等硬件结构有所了解,不易于编写、调试、维护
- 不区分大小写,比如汇编 mov和MOV是一样的
汇编的用途(俺写了这么多,看了这么多干哈阿?)
- 编写驱动程序、操作系统(比如Linux内核的某些关键部分)
- 对性能要求极高的程序或者代码片段,可与高级语言混合使用(内联汇编)
- 软件安全
- 病毒分析与防治
- 逆向\加壳\脱壳\破解\外挂\免杀\加密解密\漏洞\黑客
- 理解整个计算机系统的最佳起点和最佳有效用途
- 为编写高效代码打下基础
- 弄清楚代码的本质
- 函数的本质究竟是什么?
- ++a + ++a + ++a 底层如何执行的?
- 编译器到底帮俺们干了什么?
- DEBUG模式和RELEASE模式有什么关键的地方被俺们忽略
- ......
怎么提升逼格
越底层的东西越纯粹!真正的程序猴子都需要了解一门语言,汇编,你值得拥有!
汇编语言的种类
-
目前讨论比较多的汇编语言有
- 8086汇编(8086处理器是16bit的CPU)
- Win32汇编
- Win64汇编
- ARM汇编(嵌入式、Mac、iOS)
- 。。。。
iPhone里面用到的是ARM汇编,但不同的设备也有差异,因为CPU的架构不同。
架构 | 设备 |
---|---|
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以后 |
必要的常识
- 了解CPU等硬件结构
-
APP/程序的执行过程
- 硬件相关的最重要的是CPU/内存
- 汇编中,大部分指令都是和CPU与内存相关的
总线
- 每一个CPU芯片都有许多管脚,这些管脚和总线相连,CPU通过总线跟外部器件进行交互
- 导线的集合
- 总线的分类
- 地址总线
- 数据总线
- 控制总线
例如:
- 地址总线
- 它的宽度决定了CPU的寻址能力
- 8086的地址总线宽度是20,所以寻址能力是1M
- 数据总线
- 它的宽度决定了CPU的单词数据传送量,也就是数据数据传递速度
- 8086的数据总线宽度是16,所以单词最大传递2个字节的数据
- 控制总线
- 它的宽度决定了CPU对其他期间的控制能力、能有多少种控制(物联网有关)
内存
- 内存地址空间的大小受CPU地址总线宽度的限制。8086的地址总线宽度为20,可以定位220个不同的内存单元(内存地址范围0x00000~0xFFFFF),所以8086的内存空间大小为1MB,1024b=1kb,1024kb=1mb,1024mb=1gb 2^10 = 1024b(1kb) 2^20 = 1024kb(1mb) 2^30 = 1024mb(1gb) 1024b = 1kb 1024^2b = 1mb 1024^3b = 1gb
- 0x00000~0x9FFFF:主存储器。可读可写
- 0xA0000~0xBFFFF:向显存中写入数据,这些数据会被显卡输出到显示器。可读可写
- 0xC0000~0xFFFFF:存储各种硬件\系统信息。只读
进制
学习进制的障碍
* 很多人学不好进制,原因是总以十进制为依托去考虑其他进制,需要运算的时候也总是先转换成十进制,这种学习方法是错误的.
* 俺们为什么一定要转换十进制呢?仅仅是因为俺们对十进制最熟悉,所以才转换.
* 每一种进制都是完美的,想学好进制首先要忘掉十进制,也要忘掉进制间的转换!
进制的定义
- 八进制由8个符号组成:
0 1 2 3 4 5 6 7
逢八进 - 十进制由10个符号组成:
0 1 2 3 4 5 6 7 8 9
逢十进一 - N进制就是由N个符号组成:逢N进一
进制的简写形式
二进制 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 这就是十六进制了
数据的宽度
数学上的数字,是没有大小限制的,可以无限的大。但在计算机中,由于受硬件的制约,数据都是有长度限制的(我们称为数据宽度),超过最多宽度的数据会被丢弃,也就是说根本存不下去。
int test(){
int cTemp = 0x1FFFFFFFF;
return cTemp;
}
int main() {
printf("%x\n",test());
}
打印的结果只有 0xffffffff。
计算机中常见的数据宽度
• 位(Bit): 1个位就是1个二进制位.0或者1
• 字节(Byte): 1个字节由8个Bit组成(8位).内存中的最小单元Byte.
• 字(Word): 1个字由2个字节组成(16位),这2个字节分别称为高字节和低字节.
• 双字(Doubleword): 1个双字由两个字组成(32位)
为什么计算机存储数据它会分为有符号数和无符号数
无符号数,直接换算!
有符号数:
正数: 0 1 2 3 4 5 6 7
负数: F E D B C A 9 8
-1 -2 -3 -4 -5 -6 -7 -8
反码、补码、原码自行度娘、谷爹
自定义进制符号
通过10进制运算可以转化10进制然后查表!但是如果是其他进制
例如:
现在有9进制数 9个符号分别是:2,9,1,7,6,5,4, 8,3 逢9进1 这是进制吗?
自定义进制,可以用来加密App,预防反编译
寄存器
内部部件之间由总线连接
寄存器是中央处理器内的组成部分。寄存器是有限存贮容量的高速存贮部件,它们可用来暂存指令、数据和地址
• 对程序员来说,CPU中最主要部件是寄存器,可以通过改变寄存器的内容来实现对CPU的控制
• 不同的CPU,寄存器的个数、结构是不相同的
总结
学习汇编需要什么前提呐?
- 进制
- 内存、硬盘、CPU等硬件的结构需要一定的了解
- 寄存器一定要搞清楚
- 计算机程序运行的基本过程需要了解
- 计算机的基本存储
- 大部分的汇编都跟 CPU/内存有关
上述内容,需要多看,多查,上述内容有一定了解以后,那么就开始学习汇编吧,汇编怎么开始学习,肯定是先学习汇编指令喽!
- 汇编怎么运行?
- 都有哪些汇编指令?
- 这些指令都怎么用?
- 汇编的环境?
- 能不能跟普通代码混编?
- 运行起来应该是很高效的?
以后在慢慢去学习,哥么还得任重道远、须知学海无涯!