汇编语言
什么是汇编语言?
一般的机器语言复杂,通过简单的助记符简化了机器语言
-编译器->
加 INC 0100 0000
减 DEC 0100 1000
乘 MUL 0100 1000 0100 1000
除 DIV 0100 1000 1100 1000
程序的本质 :
隔阂!汇编一般用于底层的编写,或者单片机
C语言 C++ 面向操作系统
-编译器->
加 + 0100 0000
减 - 0100 1000
乘 * 0100 1000 0100 1000
除 / 0100 1000 1100 1000
程序员鄙视链
进制
每一种进制都是完美的!
问题 :你真的理解10进制吗? 1 + 1 = 3 对吗? !如何用进制解决这个问题。
十进制 : 0 1 2 3 4 5 6 7 8 9 1 + 1 = 2 20
我的十进制: 0 1 3 s a n v i p 9 1 + 1 = 3 30 可以自己随便定义 。
加密解密 : 程序员 用自己进制 写的程序 ! 进制的加密!
数据量大 能找到规律
进制的运算
# 八进制计算下面结果
2 + 3 = 5
2 * 4 = 10
4 + 5 = 11
4 * 5 = 24 (数 4 个 5)
# 运算的本质就是查数
0 1 2 3 4 5 6 7 10 11 12 13 14 15 16 17 20 21 22 23 24 25 26 27
#八进制计算下面的结果 九九乘法表 = 加发表!进位 计算表
277 + 333 =
277 * 54 =
237 - 54 =
234 / 4 =
八进制乘法表:
八进制的加法表:
277
333 +
-----
632
277
54 *
----
1374
1673 +
------
20324
# 减法的本质就是加法 向上加法
277
54 -
-----
223
# 除法
275
3 /
----
77
二进制
计算机 只有 0 1 状态!
物理的极限 : 摩尔定律 ! 语言的极限! 并发语言!
为什么有这么多语言?
语言在某个领域怎样做到最强!物理算力正在到达极限。本质问题。
硬操作已经到达极限,开始追求软操作的极限!
量子计算机:
可以实现量子计算的机器。提高计算机的计算力 (计算力是 核心)
单位:昆比特。(量子比特!)
量子的两个状态 。
量子比特,量子叠加态,量子纠缠,量子并行原理...
2019年。Google研究人员展示其最新54比特量子计算机,该计算机只用200秒便可计算完毕当前世界上最大的超级计算机需1万年进行的运算。
2020年,6.18号 量子体积64的量子计算机!!!
光子:正交偏振方向
磁场:电子的自旋方向
民用?
作用如此强大的计算机 我觉得民用的可能性不高,在电子计算机已经基本满足我们的生活需求的情况下,量子计算机像电子计算机一样普及我觉得是不可能的事情。快不一定对社会是好处!可能在某些方面,游戏等带来质的飞跃。但是不能让这种计算机随随便便进入我们的社会。社会就是要满足我们的基本需求的情况下又需要保护我们的安全。量子计算机会打破这种平衡!
但是是要保护普通人的已经被满足的生活需求。
还是最求随时代进步的推进更先进的生活需求呢?
社会可能被分割,在没有新的资源和土地扩展的情况下,社会根据不同的需求被分割!
传统计算机:集成电路! 0 1 硅晶片
二进制 :
0 1 10 11 100 101 110 111
二进制这么写很麻烦!二进制能否简写!
16进制
0 1 2 3 4 5 6 7 8 9 a b c d e f
1111 1111 = ff
为什么要学二进制
汇编入门理解的基础:寄存器, 内存, 位!底层的每一个位都是有含义的。
汇编高级:了解层序的深层!操作系统的内核。
数据宽度
计算机 : 内存! 给数据增加数据宽度。
bit #
Byte #### ####
Word #### #### #### ####
Dword #### #### #### #### #### #### #### ####
为什么C C++ Java 都需要定义数据的类型?
因为计算机底层需要我们这些数据定义宽度!
位 0 1
字节 0--0xFF
字 0--0xFFFF
双字 0--0xFFFF FFFF
在计算机中,每一个数据都需要给它定义类型。给它定义宽度,在内存中的宽度。
有符号数和无符号数
数据都是有宽度的,每个数据代表什么意思呢?
0 1 0 1 0 1 0 1
规则
二进制解码增加一个规则?
无符号数 规则
1001 1010 #16进制 0x9A
有符号数 规则
最高位是符号位: 1 负数 0 正数
1001 1010
如何转换?
原码 反码 补码
有符号编码规则
原码: 最高位符号位,对齐它的位进行本身绝对值即可。
反码:
- 正数:反码和原码相同
- 负数:符号位一定是1,其余位对原码取反
补码:
- 正数:反码和补码相同
- 负数:符号位一定是1,反码加1
测试
# 都是8 位
# 如果是正数 原码 反码 补码都是一样的
1
#原码 0000 0001
#反码 0000 0001
#补码 0000 0001
# 负数
-1
# 原码 1000 0001
# 反码 1111 1110
# 补码 1111 1111
-7
# 原码 1000 0111
# 反码 1111 1000
# 补码 1111 1001
# 二进制的标准
2 10
4 100
8 1000
16 10000
如果看到一个数字,二进制,需要判断是有符号数还是无符号数
位运算
计算机可以存贮所有的数字(整数,浮点数,字符),运算!
位运算
2*8最高高效的计算方式?
很多底层的调试器,需要通过位来判断CPU的状态。
**与运算(and &) **
1011 0001
1101 1000
--------- 与运算
1001 0000
或运算(or |)
1011 0001
1101 1000
--------- 与运算
1111 1001
异或运算(xor^)
# 不一样就是1
1011 0001
1101 1000
--------- 异或运算
0110 1001
非运算(not ~)
1101 1000
---------(非运算)
0010 0111
位运算(左移乘2,右移除2)
左移:(shl<<)
0000 0001 所有二进制位全部左移若干位,高位丢弃,低位补零
0000 0010
右移:(shr>>)
0000 0001 所有二进制位全部右移若干位,低位丢弃,高位补0 or 1(符号位决定)
0000 0000
int a = -10;
printf("%d
",a>>2);
位加减乘除运算
只认识0 1
基本数学建立在 加减乘除。(加法)
4+5?
# 计算机是怎么操作的!
0000 0100
0000 0101
--------(加法:计算机是不会直接加的)
0000 1001
#计算机的实现原理
# 第一步:异或 不考虑进位,异或就可以直接出结果
0000 0100
0000 0101
---------------
0000 0001
#第二步:与运算(判断进位!如果与运算结果为0,没有进位)
0000 0100
0000 0101
-----------(与运算)
0000 0100
#第三步,将与运算的结果,左移一位, 0000 1000 进位的结果
0000 10000
#第四步,异或!
0000 0001
0000 1000
-----------
0000 1001
#第五步确认这个结果 与运算(判断进位!如果与运算结果为0,没有进位)
0000 0001
0000 1000
------------
0000 0000
# 所以最终的结果就为上一次的或运算
4-5?
# 计算机是怎么操作的!
0000 0100
1111 1011
--------(减法:计算机是不会直接减的)
1111 1111 ff -1
0000 0100
1111 1011
---------- 异或(如果不考虑进位,异或就可以直接出结果)
1111 1111
0000 0100
1111 1011
---------- 与运算(如果不考虑进位,异或就可以直接出结果)
0000 0000
最终结果为
1111 1111 16 ff 10 -1
汇编语言
把上面一系列指令转换成汇编语言。让计算机执行
需要 编译器
最古老的编译器,越靠近底层
在学习汇编语言之前,需要掌握环境的配置。
1.VC6(程序到汇编的过程
2.OD
3.抓包工具
4.加密解密工具
学汇编不是为了写代码
- 理解程序的本质
《汇编语言》
16位汇编 现在大多数 计算机是 32 位
32位 和 64 位本质架构区别不大,主要是寻址能力增加。
汇编入门:了解汇编和程序的对应方式,程序的本质!
通用寄存器
寄存器:
存储顺序: CPU > 内存 >硬盘
通用寄存器 可以存任意的东西
# 32位的通用寄存器只有8个
EAX FFFF FFFF
ECX FFFF FFFF
EDX FFFF FFFF
EBX FFFF FFFF
ESP FFFF FFFF
EBP FFFF FFFF
ESI FFFF FFFF
EDI FFFF FFFF
计算机如何往寄存器中存值
对于二进制来说,直接修改值
计算机如果像寄存器中存值
mov指令
mov 存的数
mov 存的地址
内存
可以将数字写入寄存器,可以将寄存器中的值写到寄存器
计算机 : 计算力
不同的寄存器
32位 16位 8位
EAX AX AL
ECX CX CL
EDC DX DL
EBX BX BL
ESP SP AH
ENP NP CH
ESI SI DH
EDI DI BH
8位: L 低八位 H 高八位
除了通用 寄存器 其他的寄存器都有自己的特殊功能
内存
寄存器小,不够用,数据放在内存里面!
每个应用程序进程都有一个 4GB 的内存空间。虚拟内存。
程序运行的 时候 才会 用的 物理内存
1 B = 8 bit
1 kb = 1028B
1Mb = 1028KB
1Gb = 1024MB
4G = 4096 MB = 343 5973 8368 B
内存地址
存一个数:占用大小,数据宽度!存到哪里?
给每个空间起一个编号,也就是分配一个地址。
32位: 寻址能力 位 4GB
FFFF FFFF + 1 = 10000 0000 最大的值
位怎么限制内存大小。
10000 0000 内存地址* 8 = 80000 0000
转换位 10进制 /8 : 42 9496 7296
42 9496 7296 /1024/1024/1024 = 4 GB
所以 64 位 绰绰有余
每个内存地址 都有一个 编号 ! 通过这些编号 存值
内存如何存值?
- 数据宽度 : byte word dword
- 地址的位置:0xFFFFFFFF
- 不是任意的地址 ,都可以写入, 需要申请过的内存 ,才可以使用
汇编如何向内存中写值
mov 数据宽度 内存地址 .值
mov byte/word/dword/qword
mov byte ptr ds:[0x19ff70],1
传递的值的大小一定要和数据宽度相等。
内存地址写法很多
- ds:[0x19ff70 + 4] 内存地址偏移
- ds:[eax] 加寄存器
- ds:[eax + 4 ] 加寄存器 偏移
数组[]
ds:[reg + reg*{1,2,4,8}]
ds:[reg + reg*{1,2,4,8}+4]