1.1 机器语言
人和人沟通的桥梁:语言
人与计算机打交道 --> 学习计算机的语言 --> 什么是机器语言
1.2 汇编语言
这些复杂的机器语言的简化 --> 助记符:汇编语言 --> 人能够理解的语言转换成为机器能够理解的语言
离程序的本质:隔阂
汇编一般用于底层的编写,单片机…
1.3 C语言
1.4 学习思路
2.1 学习进制的障碍
十进制 --> 人类天然的选择就是十进制,十个指头 --> 跳出固有思维的方法
每一种进制都是完美的,都有自己的计算方式
2.2 进制类型
1进制
逢一进一,结绳记事
-2进制
逢二进一,计算机
-8进制
逢八进一,8个符号组成:0 1 2 3 4 5 6 7
-10进制
逢十进一,10个符号组成:0 1 2 3 4 5 6 7 8 9
-16进制
逢十六进一,16个符号组成:0 1 2 3 4 5 6 7 8 9 a b c d e f
进制并没有那么复杂,以查数为例
# 一进制
1
1 1
1 1 1
1 1 1 1
......
#二进制
0 1
10 11
100 101
110 111
1000 1001
# 三进制
0 1 2
10 11 12
20 21 22
100 101 102
110 111 112
120 121 122
......
# 七进制
0 1 2 3 4 5 6
10 11 12 13 14 15 16
20 21 22 23 24 25 26
......
60 61 62 63 64 65 66
100 101 102 103 104 105 106
......
2.3 进制的本质
就是一组符号,逢几进几
真实十进制:0 1 2 3 4 5 6 7 8 9 --> 10
我的十进制:0 2 4 6 a o e f k q --> 20 (对应真实的10)
加密解密:程序员 —— 破解程序的人 --> 进制的加密
数字量一大,总是有规律的
问题: 1 + 1 = 3 是对的吗? --> 用进制来回答这个问题
运算的本质就是 查数
结论:无论是什么进制,本身都是有一套完美的运算体系的,我们都可以通过列表的方式将它计算出来
为什么学习理解二进制:
计算机使用二进制
寄存器、内存、位,底层的每一位都是有含义的 --> 汇编入门理解的基础
硬操作:达到极限了 --> 软操作的提升:追求语言的极限——并发语言
计算机内存是有限制的 --> 给数据增加数据宽度
5.1 强类型语言
C,C++,Java都需要定义数据的类型 --> 计算机底层需要我们给这些数据定义宽度
在计算机中,每个数据都需要给它定义类型 --> 即给它定义宽度,在内存中的宽度
5.2 弱类型语言
弱类型语言不需要去定义类型,直接 let var 定义,不需要区分类型 --> 这是因为编译器帮我们做了
6.1 无符号数规则
你这个数字是什么,那就是什么
6.2 有符号数规则
最高位是符号位:1代表负数,0代表正数
有符号数的编码规则
7.1 原码
最高位为符号位,其余位 等于 这个数的绝对值的对应位
7.2 反码
正数:反码和原码相同
负数:符号位一定是1,其余位对原码取反
7.3 补码
正数:补码和原码相同
负数:符号位一定是1,反码 + 1
1
#原码 0 0 0 0 0 0 0 1
#反码 0 0 0 0 0 0 0 1
#补码 0 0 0 0 0 0 0 1
-1
#原码 1 0 0 0 0 0 0 1
#反码 1 1 1 1 1 1 1 0
#补码 1 1 1 1 1 1 1 1
-7
#原码 1 0 0 0 0 1 1 1
#反码 1 1 1 1 1 0 0 0
#补码 1 1 1 1 1 0 0 1
十进制加法: 3 + 5
#转成二进制运算
1 0
1 0 1
--------
1 0 0 0
如果看到一个数字,二进制的,需要先了解它是有符号数还是无符号数。
计算机的存储是按照补码的方式来存储的
计算机现在是可以存储所有的数字(整数,浮点数,字符)的。
8.1 为什么学习位运算
很多底层的调试器需要通过 位 来判断CPU的状态
8.2 位运算分类
8.2.1 与运算( and & )
全 1 为 1,否 则 为 0
8.2.2 或运算( or | )
全 0 才 0,否 则 为 1
学汇编不是为了写代码,是为了 理解程序的本质
寄存器:
存储数据:CPU > 内存 > 硬盘
32位CPU:寄存器有 8 16 32 位
64位CPU:寄存器有 8 16 32 64 位
通用寄存器:可以存储任何东西
32位的通用寄存器只有8个,存值的范围 0 - FFFFFFFF,对于二进制来说,直接修改值
寄存器很小,不够用 --> 数据放到内存 --> 会买的内存条
在32位操作系统中,每个应用程序进程都有4GB的内存空间,但这是空头支票
1B = 8bit
1KB = 1024B
1MB =1024KB
1GB = 1024MB
4G的内存,4096MB --> 最终计算为位,就是这个可以存储的最大容量。
内存地址存一个数 --> 占用的大小,数据宽度,存到哪里?
计算机中内存地址很多,空间很大 --> 就需要给每个空间分配一个地址 / 名字。
这些给内存起的编号,就是我们的内存地址。
32位8个16进制的值。32位:寻址能力是4GB。
FFFFFFFF+1 = 100000000,最大的值。
位是怎么限制内存大小的。
100000000内存地址*8 --> 位:800000000 --> 转换为10进制/8 --> 4,294,967,296字节
按照规则/1024,最终发现就是4GB
所以每个内存地址都有一个编号。
数据宽度: byte word dword
不是任意的地址都可以写东西的,申请使用的。只有程序申请过的内存地址我们才可以使用
#汇编如何向内存中写值。
mov 数据宽度 内存地址,1
#例如:在0x19FF70的内存地址存放一个数据宽度为byte的值为4
mov byte ptr ds : [0x19FF70],4
--> 传递的值的大小一定要和数据宽度相等
ds : [ 0x19FF70 + 4 ] 内存地址偏移
ds : [ eax ] 将寄存器的值写入到内存
ds : [ eax + 4 ] 寄存器偏移
数组底层
1.ds : [ reg + reg * { 1 , 2 , 4 , 8 } ]
2.ds : [ reg + reg * { 1 , 2 , 4 , 8 } + 4 ] 偏移