汇编语言
一,计算机的语言
1,机器语言
# 目前主流的电子计算机!
状态:0 和 1
# 最早的程序员:穿孔卡带!
加 0100 0000
减 0100 1000
乘 0100 1000 0100 1000
除 0100 1000 1100 1000
这些机器语言过于复杂,因此汇编语言诞生了,用来简化这些机器语言,他通过助记符将人类能够理解的语言转换成为机器能够理解的语言
加 INC -编译器-> 0100 0000
减 DEC 0100 1000
乘 MUL 0100 1000 0100 1000
除 DIV 0100 1000 1100 1000
汇编一般用于底层的编写,如单片机
2,C语言
加 A+B -编译器-> 0100 0000
减 A-B 0100 1000
乘A*B 0100 1000 0100 1000
除A/B 0100 1000 1100 1000

二,进制
常见的进制包括:2进制、8进制(0开头)、10进制、16进制(0x开头)
1,什么是进制
一组符号,逢几进几

测试
# 一进制 1~20
1
1 1
1 1 1
1 1 1 1
.....
# 十进制:
0 1 2 3 4 5 6 7 8 9 10
# 三进制:
0 1 2
10 11 12
20 21 22
100 101 102
# 二进制
0 1
10 11
100 101
110 111
1000
# 七进制 1~20
0 1 2 3 4 5 6
10 11 12 13 14 15 16
20 21 22 23 24 25 26
进制可以自己随便定义,用自己定义的进制来进行加密解密可以大大减少被破解的概率
2,进制的运算
进制的本质就是查数

结论:无论是什么进制,本身都是有一套完美的运算体系的,我们都可以通过列表的方式将它计算出来!

# 八进制计算下面的结果
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
3,二进制
计算机使用二进制 0 1 ! 状态!电子!
物理极限:摩尔定律(其核心内容为:集成电路上可以容纳的晶体管数目在大约每经过18个月便会增加一倍。换言之,处理器的性能每隔两年翻一倍)!硬操作!
语言极限: 并发语言软操作!
量子计算机
量子计算机Scientific Reports:https://www.nature.com/collections/gdgdeidbea/?utm_source=so360&utm_medium=cpc&utm_content=null&utm_campaign=JRCN_4_SM01_CN_Scirep_EC_QuantumComput_360
可以实现量子计算的机器。
传统的计算机:集成电路!0 1 。 硅晶片!
量子计算机的单位:昆比特。(量子比特!)量子的两态来表示。
光子:正交偏振方向。
磁场:电子的自旋方向。
21世纪。计算力。快到尽头了! 【本质问题】!
量子计算机! 提高计算机的计算力。
量子比特、量子叠加态、量子纠缠、量子并行原理…
2019年,Google研究人员展示其最新54比特量子计算机,该计算机只用200秒便可计算完毕当前世界最大的超级计算机需1万年进行的运算。
2020年,6.18霍尼韦尔宣布已经建造了目前世界上性能最好的量子计算机,量子体积达到64,其性能是下一代量子计算机的两倍,甚至超过了谷歌、IBM、英特尔的同类产品。
霍尼韦尔还表示,将在一年之内得到至少10个有效量子比特,相当于1024个量子体积。量产!
2020年6月和8月,霍尼韦尔、IBM这两家科技巨头先后宣布其64量子体积的量子计算机性能全球第一。2020年9月,中科院院士潘建伟教授宣布团队已经完成对50个光子的玻色取样,相比谷歌的“量子优越性”快100万倍。越来越多的学者宣称量子计算机即将成为现实。根据现在的进展,我们可以肯定地说,当21世纪结束的时候,本世纪将会被归纳为“量子计算”的世纪。
电子计算机 == >量子计算机!
电子计算机!0 1 !
二进制:
0 1 10 11 100 101 110 111 1000 1001 1010 1011 1100 1101 1110 1111
二进制这么去写很麻烦!二进制能否简写!16进制
0 1 2 3 4 5 6 7 8 9 a b c d e f
为什么要学习理解二进制?
寄存器、内存、位!底层的每一个位都是有含义的。汇编入门理解的基础!
汇编高级:了解程序的深层!操作系统的内核
三,数据宽度
计算机:内存!给数据增加数据宽度。
byte范围:-128~127
0 48
A 65
a 97
默认转换:byte,short,char–>int–>long–>float–>double
long:8个字节
float:4个字节
A:它们的底层的存储结构不同
B:float表示的数据范围比long的范围要大
long:2^63-1
float:3.4*10^38>2^63-1
指数有正有负,注意指数位采用移位存储,偏移量为127,假设指数为2,那么指数码表示为129的二进制形式,即10000001
java语言中的字符char可以存储一个中文汉字,因为java语言中的字符占用两个字节

C 和 C++ Java都需要定于数据的类型。计算机底层需要我们给这些数据定义宽度。
位 0 1
字节 0~0xFF 8位
字符 0~0xFFFF 16位
双字符 0~0xFFFFFFF 32位
在计算机中,每一个数据都需要给它定义类型。给它定义宽度。在内存中的宽度。
四,有符号数和无符号数及源码,反码,补码
1,有符号数和无符号数
数据都是有宽度的。每个数据代表什么意思呢?
无符号数规则:
你这数字是什么,那就是什么。
1 0 0 1 1 0 1 0 十六进制:0x9A 十进制 154
有符号数规则:
最高位是符号位:1 (负数) 0(正数)
1 0 0 1 1 0 1 0
2,源码,反码,补码
正数的原,反,补码都相同
计算机采用补码,是对补码进行操作
符号位为0是正数,符号位为1是负数
编码规则
1,无符号数的编码规则:
无符号数和正数 原反补码 一样
2,有符号数的编码规则
原码: 最高位符号位,对齐它的为进行本身绝对值即可。
反码:
正数:反码和原码相同
负数:符号位一定是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得到补码
-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最高效的计算方式?
这道题不论怎样都非常慢,只有通过位运算才是最快的,比如左移、右移。而且要记住一句话:很多底层的调试器(例如C语言调试器),当我们手写调试器的时候就需要通过位来判断CPU的状态。
与运算

1011 0001
1101 1000
-------------------- 与运算的结果
1001 0000
或运算

1011 0001
1101 1000
--------------- 或运算
1111 1001
异或运算
相同为0,不同为1

1011 0001
1101 1000
--------------------异或运算
0110 1001
非运算
0变1 1变0 (源码,反码)
通过这些可以完成我们的加减乘除。怎么通过位运算实现加减乘除呢?
位运算(移动位)(左移*2,右移/2)
左移(shl <<)
0000 0001 所有的二进制位全部左移若干位,高位就丢弃,低位补0
0000 0010
右移(shr >>)
0000 0001 所有二进制全部右移若干位,低位就丢弃,高位补0或1(根据符号位决定,负数补1,正数补0)
0000 0000
如果想要取值(C++)
int a = 10;
printf("%d\n",a>>2);
无符号右移(>>>)
无论最高位是0还是1,左边补齐0
总结: 汇编的本质就是操作二进制。
通过二进制、位运算实现 加减乘除。
六,位运算加减乘除
计算机只认识0 1。
基本数据是建立在加、减、乘、除上的。
例子:求4+5?
计算机是如何操作的呢?
0000 0100
0000 0101
-------------------------(加法,计算机是不会直接加)
0000 1001
那么计算机的实现原理是什么呢?
怎么将两个数加起来?核心是:异或。
第一步,异或:如果不考虑进位,异或就可以直接出结果
0000 0100
0000 0101
-------------------------
0000 0001
第二步,与运算(判断进位),如果与运算结果为0,那么就没有进位。
0000 0100
0000 0101
-------------------------
0000 0100
第三步,将与运算的结果左移一位。
0000 0100 ——> 0000 1000 (进位的结果)
第四步,还是一个异或运算。(第一步异或出来的结果和第三步与运算的进位结果再一次异或)
0000 0001
0000 1000
------------------------
0000 1001
确认结果是对的:
第五步,再去做一个与运算,判断它是否有进位。(与第二步一样)
0000 0001
0000 1000
------------------------
0000 0000
最后一步与运算结果为
0000 0000
电路都断了,灯泡全灭,通过不了
所以最终结果就是:与运算为0的结果的上一个异或运算结果:
0000 1001 (二进制的9)
如果与运算不为0,继续循环。
例子:求4-5
我们说了,计算机没有所谓的减法,那么计算机是如何操作的呢?
4-5 说白了就是 4+(-5)
0000 0100
1111 1011 (代表二进制的-5)
------------------------(减法,计算机是不会直接减)
1111 1111(8个1就是ff,所以ff在十进制中代表-1)
0000 0100
1111 1011
------------------------ 异或(如果不考虑进位,异或就可以直接出结果)
1111 1111
0000 0100
1111 1011
------------------------ 与运算(判断进位),如果与运算结果为0,那么就没有进位。
0000 0000
最终结果
1111 1111 (十六进制的ff,十进制的-1)
例子:
乘法: x * y,本质就是y个x相加,还是加法。
除法: x / y,本质就是减法,就是x能减去多少个y。
结论:
计算机只会做加法!
目前为止,我们可以从零设计一套自己的进制规则。自己设计电路来实现加减乘除。但是最终乘除的结果是一个二进制,例如:我们有32个灯泡,就可以显示32个数值,最终亮起灯泡的数就是最终的结果。手动转换这个结果和值!(十进制和二进制的转换)
机器语言并不会做很多事情,它很“笨”。机器语言说白了就是位运算,(加减乘除)
都是电路来实现的。这就是计算机最底层的本质。
通过机器语言来实现加法计算器,这就是设计电路。
七,汇编语言环境说明
我们通过指令来代替我们的一些二进制编码!比如说:刚才的加法运算是通过各种操作能否通过一个符号计算呢?比如说我就想叫它(ADD指令),假设我给计算机发一个ADD指令,它通过识别我的指令转换成机器语言(也就是编译)ADD指令转换为二进制操作。

通过汇编指令可以给计算机发一些操作,然后让计算机执行。编译器。
在学习汇编之前,先要掌握环境的配置:
1,Vc6(程序到汇编的理解,通过C语言实现)
2,OD
3,抓包工具
4,加密解密工具
学汇编不是为了写代码,就是为了理解程序的本质。

如果我们是一个做应用的程序员,别人调试不了的程序,如果学过汇编,都可以调试。因为知道底层堆栈到底做了什么。如果是做安全的(反外挂,反病毒),就要理解汇编到二进制的全部知识。
现在的计算机至少是32位,还有的是64位。我们要知道,它是由32位演化过来的。底层架构没有发生变化,只是多了寄存器,主要是寻址能力增加。
汇编入门: 了解汇编和程序的对应关系,程序的本质即可。

八,通用寄存器
寄存器:
存储数据:CPU > 内存 > 硬盘
32位 CPU 8 16 32
64位 CPU 8 16 32 64
32位的通用寄存器只有8个:

寄存器中的存值范围:0 ~ FFFFFFFF
计算机如何向寄存器中存值呢?
对于二进制来说,就是直接修改值。但是修改值需要找到对应的位置,所以才有内存地址。
mov 存的地址,存的数
mov 存的地址1,存的地址2

可以将数字写入到寄存器,也可以将寄存器中的值,写到寄存器。
不同的寄存器:
32位代表八个F(FFFF FFFF),一个F代表4位(1111)
FFFF FF
32位 16位 8位(0000 0000)
EAX AX AL(A L )
ECX CX CL
EDX DX DL
EBX BX BL
ESP SP AH
EBP BP CH
ESI SI DH
EDI DI BH
对于8位:L代表低8位,H代表高8位
16位是FFFF 高八位占前两个FF,低八位占后两个FF

除了这些通用寄存器之外,那么其他的寄存器每一位都有自己特定的功能(比如:开机关机)。
我们一般写值都会写到通用寄存器中。
九,内存
寄存器很小,而且不够用。所以我们会把数据放到内存中。
有句话:每个应用程序进程都有4GB的内存空间。 程序用的内存就是空头支票,虽然每个应用程序的进程都有4GB内存空间,但是真正到机器上使用时候并没有那么大。

程序真正运行的时候,才会用到物理内存。
1B = 8bit
1KB = 1024B
1MB = 1024KB
1GB = 1024MB
假设是4GB内存电脑,就等于4096MB => 最终计算为位,就是可以存储的最大容量。
计算机中的内存地址很多,空间很大。
内存地址:
存一个数:占用大小,数据宽度。存到哪里呢?
计算机中的内存地址很多,空间很大。我们要给空间取名字,每个空间分配一个地址,名字。

这些给内存起的编号就是我们的内存地址。32位(8个十六进制的值)
32位:决定寻址能力!
FFFFFFFF + 1 = 100000000,最大的值。
位是怎么限制内存大小呢?
100000000 内存地址 * 8位 :800000000。
转换为十进制 / 8:4,294,967,296字节。
按照规则/1024最终发现就是 4GB(不能超过)。
64位,绰绰有余。
所以每个内存地址都有一个编号:可以通过编号向里面存值:

内存如何存值?(mov指令)
存值需要知道数据宽度(byte word dword),地址位置(自定义:0xFFFFFFFF)
不是任意的地址都可以写东西,只有程序申请过的内存地址我们才可以使用。
汇编如何向内存中写值:
mov 数据宽度 内存地址,1
mov byte ptr ds:[0x19ff70],1
传递的值的大小一定要和数据宽度要相等,如果大放不进去。

内存地址有多种写法:
1,ds:[0x19FF70+4](内存地址偏移):加 偏移(4),地址就变成了:0x19FF74
2,ds:[eax](寄存器):把寄存器中的值放到内存中。
3,ds:[eax + 4](寄存器偏移)
以数组为例:
ds:[reg + reg * {1,2,4,8}]
ds:[reg + reg * {1,2,4,8} + 4] 偏移
本文介绍了计算机语言的基础,从机器语言到C语言,重点讲解了二进制及其运算,包括进制转换、二进制在量子计算机中的应用。讨论了数据宽度、有符号数与无符号数的表示,并详细阐述了位运算,如与、或、异或和移位。最后,文章概述了汇编语言环境和汇编指令的重要性,为理解计算机底层运作提供基础。

6383

被折叠的 条评论
为什么被折叠?



