狂神学习笔记
机器语言
什么是机器语言?
#目前主流的电子计算机
状态 0 和 1
#最早的程序员 穿孔卡带
加 0100 1000
减 0001 1100
乘 0110 1010 0001 1000
除 0110 1010 0001 1001
这些复杂的机器语言能简化么?助剂符!汇编语言!人们能够理解的语言转换称为机器能够理解的语言!
加 INC-编译器-> 0100 1000
减 DEC 0001 1100
乘 MUL 0110 1010 0001 1000
除 DIV 0110 1010 0001 1001
程序的本质:隔阂!汇编一般用于底层的编写。单片机......
C语言
加 A+B -编译器-> 0100 1000
减 A-B 0001 1100
乘 A*B 0110 1010 0001 1000
除 A/B 0110 1010 0001 1001
进制
二进制? 0 1
学习进制的障碍?
10进制!
人类天然的选择就是10进制,10个手指。跳出固有的思维方式!屈指可数!
二进制
思想:每一种进制都是完美的,都有自己的计算方式!
进制?
1进制:1进一。结绳记事。1 1
2进制:2进一。计算机
8进制:8进一。8个符合组成:0 1 2 3 4 5 6 7
10进制:10进一。10个符合组成:0 1 2 3 4 5 6 7 8 9
16进制:16进一。16个符合组成:0 1 2 3 4 5 6 7 8 9 a b c d e f
进制远远没有想象的复杂:查数
问题:你真的理解进制了吗?1+1=3?如果可以利用进制回答这个问题,那么真的学会了!
十进制 0 1 2 3 4 5 6 7 8 9
自己的十进制 5 7 8 2 3 a b g u i ,可以自己随便定义
加密解密:程序员,破解程序的人!进制的加密 数据量一大总会有规律
进制运算
#八进制计算下边的结果
2+3=5
2*3=6
4+5=11
4*5=24
#运算的本质就是查数
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
276*54
237-54
234/4
八进制的乘法表
八进制的加法表
277
333 +
----------
632
237
54 -
-----------
163
276
54 *
--------
1370
1666
---------
20250
234
----
4 47
结论:无论是什么进制,本身都是有一套完美的运算体系的,我们都可以通过裂变的方式将他计算出来!例如:九九乘法表!
二进制
计算机使用二进制 0 1 状态 !电子!物理极限:摩尔定律!硬操作!追求语言的极限!并发语言!软操作!
量子计算机:可以实现量子计算的机器。
传统的计算机:集成电路 0 1 .硅晶片
量子计算机的单位:昆比特(量子比特)量子的两态来表示。
光子:正交偏振方向。
磁场:电子自旋方向。
21世纪,计算力快到尽头了!
量子计算机!提高计算机的计算力。
量子比特,量子叠加态,量子纠缠,量子并行原理......
2019年,Google研究人员展示其最新54比特量子计算机,该计算机只用200秒便可计算完毕当前世界最大的超级计算机需要一万年进行的计算。
2020年,6.18量子体积64的量子计算机!!!
目前......
电子计算机-->量子计算机!!
回到电子计算机~0 1
二进制 :0 1111
0 1 10 11 100 101 110 111 1000 1001 1010 1011 1100 1101 1110 1111
二进制这样写很麻烦!二进制能否简写!
0 1 2 3 4 5 6 7 8 9 a b c d e f
这就是我们的16进制
为什么要学习理解二进制
寄存器、内存、位!底层的每一位都是有含义的。汇编入门理解的基础。
汇编高级:了解程序的深层!操作系统的内核?
数据宽度
计算机:内存!给数据增加数据宽度。
C C++ Java 都需要定义数据的类型,计算机的底层需要我们给这些数据定义宽度。
位 0 1
字节 0-0xff
字 0-0xffff
双字 0-0xffffffff
在计算机中,每一个数据都需要给它定义类型。给它定义宽度,在内存中的宽度。
有符号数无符号数
数据都是由宽度的,每个数据代表什么意思?
0 1 0 1 0 1 0 1
规则,二进制解码增加一个规则?
无符号数的规则
你这个数字是什么,那就是什么。
1 0 0 1 1 0 1 0 十六进制 0x9a 十进制 154
有符号数的规则
最高位是符号位 1 (负数)0 (正数)
1 0 0 1 1 0 1 0 如何转换?
原码反码补码
编码规则
有符号数的编码规则
原码:最高位符号位,其他的为本身的绝对值即可
反码:
- 正数:反码和原码相同
- 负数:符号位一定是1,其余位对原码取反
补码:
- 正数:补码和原码相同
- 负数:符号位一定是1,反码+1
测试
#现在所说的都是8位
#如果是正数,那都是一样的
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
如果我们看到一个数字,二进制的,需要了解它是有符号还是无符号的
寄存器:mov 寄存器 值 计算机存储的正数为本身 负数则为补码。
位运算
计算机可以存储所有的数字(正数、浮点数、字符)。运算!
运算?
2*8最高效计算方式。
很多的底层调试器,需要通过位来查看CPU的状态。
与运算(and &)
计算机的本质。
1001 1100
1011 1111
--------- 与运算
1001 1100
或运算(or |)
1001 1100
1011 1111
--------- 或运算
1011 1111
异或运算(xor ^)
不一样就是1 。
1001 1100
1011 1111
--------- 异或运算
0010 0011
非运算(单目运算符 not ~)
0就是1 1 就是0,取反
1001 1100
--------- 非运算
0110 0011
通过这些可以完成加减乘除!位运算来实现加减乘除!
位运算(移动位)
左移:( shl <<)
0 0 0 0 0 0 0 1 所有二进制位全部左移若干位,高位丢弃,低位补0
0 0 0 0 0 0 1 0
右移:(shr >>)
0 0 0 0 0 0 0 1 所有二进制位全部右移若干位,低位丢弃,高位补0,1(符号位决定)
0 0 0 0 0 0 0 0
0000 0001 1
0000 0010 2 #左移1位
0000 0100 4 #左移2位
0000 1000 8 #左移3位
位运算的加减乘除
计算机只认识0 1
基本数学是建立在加减乘除。(加法)
4+5?
#计算机是怎么操作的
0000 0100
0000 0101
--------- 加法:计算机是不会直接加的
0000 1001
#计算机的实现原理
#1 异或,如果不考虑进位,异或就可以直接出结果
0000 0100
0000 0101
--------- 异或
0000 0001
#2 与运算(判断进位,如果与运算结果为0,没有进位)
0000 0100
0000 0101
---------与运算
0000 0100
#3 与运算不为0则包含进位,将与运算结果,左移一位
0000 0100
---------左移一位
0000 1000
#4 异或,将1中结果与3中的结果继续进行异或操作
0000 0001
0000 1000
---------异或
0000 1001
#5 与运算(判断进位,如果与运算结果为0,没有进位,结束操作,否则重复执行上述操作步骤)
0000 0001
0000 1000
---------与运算
0000 0000
#所以最终的结果就是与运算为0的结果的上一个步骤异或运算的结果。
0000 1001
4-5?
#计算机是怎么操作的
#计算机存储正数为本身,负数为补码
4+(-5)
0000 0100
1111 1011
--------- 加法:计算机是不会直接减的
1111 1111
#计算机的实现原理
#1 异或,如果不考虑进位,异或就可以直接出结果
0000 0100
1111 1011
--------- 异或
1111 1111
#2 与运算(判断进位,如果与运算结果为0,没有进位)
0000 0100
1111 1011
---------与运算
0000 0000
#所以最终的结果就是与运算为0的结果的上一个步骤异或运算的结果。
1111 1111
乘:x*y ,就是y个x相加,还是加法
除:x/y ,就是x能减去多少个y,本质是减法
计算机只会做加法!
机器语言就是位运算。都是由电路来实现的,这就是计算机最底层的本质!
汇编语言环境说明
通过指令代替我们的二进制编码。
通过汇编指令可以给计算机法一些操作,然后让计算机执行。编译器的发展,底层的大佬,几乎都是最原始的IDE。
学习汇编之前需要掌握的环境配置(1 Vc6 程序到汇编的理解 2 OD 3 抓包工具 4 加密解密工具)
学习汇编不是为了写代码
理解程序的本质
《汇编语言》16位的汇编, 32位 64位 本质架构区别不大,寻址能力增加。
汇编入门:了解汇编和程序的对应关系,程序的本质即可!
通用寄存器
寄存器:存储数据 CPU>内存>硬盘
32位的CPU 8 16 32
64位的CPU 8 16 32 64
通用寄存器
32位的通用寄存器只有8个
4个数据寄存器(EAX、EBX、ECX和EDX)
2个变址和指针寄存器(ESI和EDI)
2个指针寄存器(ESP和EBP)
存值的范围 0~FFFFFFFF
计算机如何向寄存器存值
mov指令
mov 存的地址,存的数 可以将数字写入寄存器
mov 存的地址1,存的地址2 可以将寄存器中的值写入寄存器
计算机 :计算力!!
不同的寄存器
FFFFFFFF FFFF FF
32位 16位 8位
EAX AX AL
EBX BX BL
ECX CX CL
EDX DX DL
ESI SI AH
EDI DI BH
ESP SP CH
EBP BP DH
8位:L低8位 H 高8位
内存
寄存器很小,不够用。所以说,数据放到内存!
平时买的内存条!
每个应用程序都有4g的内存空间,空头支票。
程序真正运行的时候才会用到物理内存!
1B=8bit
1KB=1024B
1MB=1024KB
1GB=1024MB
4GB的内存=4096MB==>最终计算为位,就是这个可以存储的最大容量。
计算机内存地址很多,空间很大。
内存地址
存一个数:占用的大小,数据宽度?存到哪里?
计算机中内存地址很多,空间很大,每个空间分配一个地址,名字
这些给内存起的编号,就是我们的内存地址。32位 8个16进制的值
32位的寻址能力:4GB 。
FFFFFFFF+1=100000000,最大值。
位是怎么限制内存大小的。
100000000内存地址*8=位:800000000
转换为10进制/8=4,294,967,296字节,按照规则/1024,最终发现就是4GB!
每个内存地址都有一个编号,可以通过这些编号向里边存值!
内存如何存值?
数据宽度:byte word dword
地址位置:0xFFFFFFFF
不是任意的地址都可以写入的,需要申请使用。只有程序申请过的内存才可以使用
#汇编如何向内存写值
mov 数据宽度 内存地址,值
mov byte/word/dword/qword ptr ds:[0x12FF12],1
传递的值得大小一定要和数据宽度相等
内存地址由多种写法
ds:[0x12FF12] #基本写法
ds:[0x12FF12+4] #内存地址偏移
ds:[exa] #寄存器
ds:[exa+4] #寄存器偏移
ds:[reg+reg*{1,2,4,8}] #数组
ds:[reg+reg*{1,2,4,8}+4] #偏移
未完待续.......
汇编指令
内存复制
堆栈指令
汇编如何写函数
堆栈传参
堆栈平衡
外挂