了解汇编语言

本文介绍了计算机语言的基础,从机器语言到C语言,重点讲解了二进制及其运算,包括进制转换、二进制在量子计算机中的应用。讨论了数据宽度、有符号数与无符号数的表示,并详细阐述了位运算,如与、或、异或和移位。最后,文章概述了汇编语言环境和汇编指令的重要性,为理解计算机底层运作提供基础。

一,计算机的语言

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] 偏移

十,汇编指令

十一,内存复制

十二,堆栈的指令

十三,汇编如何写函数

十四,堆栈传参

十五,堆栈平衡

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值