计算机底层,二进制到汇编学习
语言
1.1什么是极其语言?
-
最早的计语言算机只用0和1表示;
-
本质还是进行加、减、乘、除;
这些复杂的机器语言能简化吗?这时候就有了助记符! INC(加)、DEC(减)、MUL(乘)、DIV(除)。
进制
-
什么是进制?
-
进制就是逢几进1;
-
如:
1进制:结绳记事 1 1
2进制:逢2进一 0 1 10 11...
8进制:只存在0 - 7
16进制:0 1 2 3 4 5 6 7 8 9 a b c d e f
你真的了解进制吗?一个问题:1 + 1 = 3吗?
进制是人创造出来的一组符号罢了,如果可以,我们自己也能创作自己想要的进制
密解密:
我们通过自己定义的一组进制按照规则进行加密解密。
进制的计算
# 八进制计算下面的结果:
2 + 3 = 5
2 * 3 = 6
3 + 4 = 7
3 * 4 = 14
# 运算的本质是查数
0 1 2 3 4 5 6 7 10 11 12 13 14 15 16 17 20 21 22 23 24 25 ...
# 再次用八进制进行计算
234 + 543 = ?
345 * 123 = ?
八进制乘法表
1 * 1 = 1 | ||||||
---|---|---|---|---|---|---|
1 * 2 = 2 | 2 * 2 = 4 | |||||
1 * 3 = 3 | 2 * 3 = 6 | 3 * 3 = 11 | ||||
1 * 4 = 4 | 2 * 4 = 10 | 3 * 4 = 14 | 4 * 4 = 20 | |||
1 * 5 = 5 | 2 * 5 = 12 | 3 * 5 = 17 | 4 * 5 = 24 | 5 * 5 = 31 | ||
1 * 6 = 6 | 2 * 6 = 14 | 3 * 6 = 22 | 4 * 6 = 30 | 5 * 6 = 36 | 6 * 6 = 44 | |
1 * 7 = 7 | 2 * 7 = 16 | 3 * 7 = 25 | 4 * 7 = 34 | 5 * 7 = 43 | 6 * 7 = 52 | 7 * 7 = 61 |
八进制加法表
1 + 1 = 2 | ||||||
---|---|---|---|---|---|---|
1 + 2 = 3 | 2 + 2 = 4 | |||||
1 + 3 = 4 | 2 + 3 = 5 | 3 + 3 = 6 | ||||
1 + 4 = 5 | 2 + 4 = 6 | 3 + 4 = 7 | 4 + 4 = 10 | |||
1 + 5 = 6 | 2 + 5 = 7 | 3 + 5 = 10 | 4 + 5 = 11 | 5 + 5 = 12 | ||
1 + 6 = 7 | 2 + 6 = 10 | 3 + 6 = 11 | 4 + 6 = 12 | 5 + 6 = 13 | 6 + 6 = 14 | |
1 + 7 = 10 | 2 + 7 = 11 | 3 + 7 = 12 | 4 + 7 = 13 | 5 + 7 = 14 | 6 + 7 = 15 | 7 + 7 = 16 |
234
+ 543
---------
777
345
* 123
-----------
1257
712
345
-----------
45077
二进制(计算机使用二进制 0 1)
-
什么是量子计算机?
-
可以实现量子计算的计算机
-
传统的计算机:集成电路(0 和 1)
-
量子计算机的单位:昆比特(量子比特),量子也有两种状态来表示
-
-
为什么要学二进制?
-
寄存器、内存、位!底层的每一位都是有含义的。这是汇编入门的基础!
-
汇编高级:了解计算机的深层;
-
数据宽度
注意:c、c++和Java都需要定义数据类型,计算机底层需要我们给这些数据定义宽度。
-
位:0~1
-
字节:0~0xFF
-
字:0~0xFFFF
-
双字:0~FFFFFFFF
有符号数与无符号数
数据都是有宽度的,每个数据代表什么意思呢?
规则:二进制解码会有一个规则
-
无符号规则:你这个数字是什么就是什么
1 0 0 1 1 0 1 0 十六进制:0x9A 十进制:154
-
有符号规则(最高位是一个符号):1代表负数,0代表正数
1 0 0 1 1 0 1 0 符号该如何转换进制?
原码、补码、反码
编码规则:有符号数的编码规则
原码:最高位符号位
反码:
-
正数:反码与原码相同
-
负数:最高位(符号位)一定为1,其余位取反
补码:
-
正数:补码与原码相同
-
负数:最高位(符号位)一定为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
位运算
计算机现在可以储存所有的数字(整数、浮点数、字符)的运算
-
与运算(and&):相同为1,否则为0
1011 1101
1001 1010
----------
1001 1000
-
或运算(or|):只要一个为1,则为1
1010 1110
1011 1101
----------
1011 1111
-
异或运算(xor^):不一样就是1,否则为0
1101 1011
1000 1011
------------
0101 0000
-
非运算(单目运算符 not~):0就是1,1就是0,就是我们说的取反
1011 1100
-----------
0100 0011
-
位运算
-
左移(shl<<):所有二进制位全部左移若干位,高位丢弃,低位补0
0000 0001 # 进行左移
---------
0000 0010 -
右移(shr>>):所有二进制位全部右移,低位丢弃,高位需要补0或1(符号位决定)
0000 0001 # 进行右移
----------
0000 0000
-
位运算的加、减、乘、除
计算机本质就是进行了加减乘除,那么用二进制来计算一下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
# 第六步:因为没有进位,所以第五步是最终的结果,如果依然有进位,则再次循环,直到没有进位为止
那么计算机怎么计算减法呢? 计算一下4 - 5 = ?
# 计算机底层减法的实现本质还是做了一个加法 4 + (-5) = ?
# 第一步:进行亦或运算
0000 0100
1111 1011 # 计算机里面负数的表示取的是补码:先取反再加1
--------------
1111 1111
# 第二步:进行与运算判断是否有进位
0000 0100
1111 1011
-----------
0000 0000
# 这里没有进位,所以第一步直接出结果
那么计算是怎么做乘法和除法呢?
-
x*y,就是x个y相加,本质还是加法
-
x/y,做的就是一个减法,就是x能减多少个y,而减法的本质还是做加法
结论:计算机底层只会做加法!
汇编语言
机器语言进行的运算是很麻烦的一件事,那么可不可以简化呢?
这时,汇编语言就是通过简单的指令代替二进制编码
学习汇编之前,需要掌握环境的配置:
-
VC6(程序到汇编的理解)
-
OD
-
-
加密解密工具
学汇编不是为了写代码,写代码的本质是理解程序的本质。
通用寄存器
寄存器:
存储数据:CPU > 内存 > 硬盘
32位CPU : 8 16 32
64位CPU : 8 16 32 64
# 32位的通用寄存器只有8个
32位 16位 8位(L代表低8位,H代表高8位)
EAX AX AL
ECX CX CL
EDX DX DL
EBX BX BL
ESP SP AH
EBP BP CH
ESI SI DH
EDI DI BH
存值的范围 0 ~ FFFFFFFF
计算机是如何向寄存器存值的呢?
-
对于二进制来说,直接修改值即可
-
汇编用到mov指令:mov 寄存器,要存的值(可以将数字写入到寄存器,也可以将一个寄存器的值写到另一个寄存器)
内存
寄存器很小,不够用,所有我们要把数据放入内存中
我们平时买的内存条
内存地址:
-
计算机中内存地址很多,空间很大,每个空间需要分配一个地址(名字)
-
存一个数:占用的大小,数据宽度,存到哪里?
32位:寻址能力!4GB
FFFFFFFF + 1 = 10000000,最大的值
位是怎么限制内存大小的呢?
100000000内存地址 * 8 = 位:800000000
按照规则除以1024,最终得出是4GB
所以64位绰绰有余!
-
每个内存都有一个编号,我们可以通过编号向内存里存值
-
内存该如何存值?
-
需要有数据宽度:byte(字节)、word(字)、dword(双字)
-
需要地址的位置
# 汇编如何向内存中存值?
mov 数据宽度 内存地址,值
如:mov byte ptr ds:[0x19FF70],1 -
-
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南