底层原理基础01

语言

人和人沟通需要语言 人和计算机沟通 需要学习计算机的语言

什么是机器语言?

进制

进制?

1进制 逢1进一 结绳记事

2进制 逢2进一 计算机

八进制 逢8进一 八个符合组成 0 1 2 3 4 5 6 7

10进制 逢10进一 十个符号组成 0 1 2 3 4 5 6 7 8 9

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

小刘的十进制 0 1 2 3 4 5 a b c d

加密解密 程序员 破解程序的人 是进制的加密

但是 数字量一大 总是有规律的

进制怎么运算

八进制加法表

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=11
1+6=7 2+6=10 3+6=11 4+6=12 5+6=12 6+6=13
1+7=10 2+7=11 3+7=12 4+7=13 5+7=13 6+7=14 7+7=15

八进制乘法表

1*1=1 1*2=2 1*3=3 1*4=4 1*5=5 1*6=6 1*7=7
2*2=4 2*3=6 2*4=10 2*5=12 2*6=14 2*7=16
3*3=11 3*4=14 3*5=17 3*6=22 3*7=25
4*4=20 4*5=24 4*6=30 4*7=36
5*5=31 5*6=36 5*7=43
6*6=44 6*7=52
7*7=61

运算的本质就是查数 根据对应的88乘法表来查数

二进制

二进制
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	

数据宽度

计算机 内存 给数据增加数据宽度

image-20240521223427445

C C++ Java都需要定义数据的类型 计算机的底层需要我们给这些数据定义宽度

位 0 1

字节 0 0xFF

字 0 0xFFFF

双字 0 0xFFFF FFFF

在计算机中 每一个数据都需要给它定义数据类型 给它定义宽度 在内存中的宽度

有符号数 和 无符号数

数据都是有宽度的 每个数据代表什么意思呢? 二进制

0 1 0 1 0 1 0 1

规则 二进制解码增加一个规则?

无符号规则 -->

你这个数字是什么 那就是什么

1001 1010	十六进制	0x9A	

有符号规则 -->

最高位是符号位 1 (负数) 0 (正数)

1001 1010	如何转换?

原码反码补码

有符号数的编码规则

原码 最高位是符号位 对其他的位进行本身的绝对值就行

反码

  • 正数 反码和原码相同
  • 负数 符号位一定是1 其余位对源码取反

补码

  • 正数 补码和原码相同
  • 负数 符号位一定是1 反码+1

测试

6
# 原码	0 0000 0110
# 反码	1 1111 1001
# 补码	1 1111 1010

-6
# 原码	1 0000 0110
# 反码	1 1111 1001
# 补码	1 1111 1010
# 2进制的标志
2	10
4	100
8	1000

FF	255	1111 1111	

如果看到一个二进制的数字 需要了解它是有符号数还是无符号数

位运算

位运算

2*8最高效的计算方式

很多底层的调试器 需要通过位来判断CPU的状态

与运算 ( and & ) --> 二目运算符 需要两个数字进行运算

image-20240522124427852

1011 0001
1101 1000
----------	与运算
1001 0000

或运算 ( or | ) --> 二目运算符 需要两个数字进行运算

image-20240522125037031

1011 0001
1101 1000
-----------  或运算
1111 1001

异或运算 ( xor ^ ) --> 二目运算符 需要两个数字进行运算

不一样就是1 一样就是0

1可以理解为 亮灯 0可以理解为 不亮灯

image-20240522125610284

1011 0001
1101 1000
-----------  异或运算
0110 1001

非运算 (not ~ ) --> 单目运算符

0就是1 1就是0

1101 1000
-----------  非运算
0010 0111

将原码变成反码的过程

通过这些可以完成加减乘除 通过位运算来实现加减乘除

位运算 ( 移动位 左移*2 右移/2)

左移 (shl <<)

0000 0001	所有的二进制位全部左移若干位	高位丢弃 , 低位补0
0000 0010

右移 (shr >>)

0000 0001	所有的二进制位全部右移若干位	低位丢弃 , 高位补0,1(符号位决定)	如果是负数就补1  正数补0
00000 000

0000 0010
00000 001

int a = 10;
printf("%d\n",a>>2);

位运算的加减乘除

4+5=?

# 计算机是怎么操作的
0000 0100
0000 0101
----------	加法	但是计算机是不会直接加的	这样的加法过程是我们人自己加的
0000 1001

# 计算机的实现原理

# 第一步  异或  如果不考虑进位  异或就可以直接出结果
0000 0100
0000 0101
----------	异或
0000 0001

# 第二步  与运算  判断进位	如果与运算结果为0  没有进位
0000 0100
0000 0101
----------	与
0000 0100

# 第三步  将与运算的结果  左移一位  进位结果  0000 1000
0000 0100
----------  左移<<
0000 1000

# 第四步  异或  将第一步异或的结果  第三步左移一位的结果  进行异或运算
0000 0001
0000 1000
----------  异或
0000 1001

# 第五步  与运算  判断进位	如果与运算结果为0  没有进位
0000 0001
0000 1000
----------  与
0000 0000

# 所以最终的结果就是  与运算为0的结果的上一个异或运算
4 + 5 = 9
0000 0100 + 0000 0101 = 0000 1001 = 9

4-5=?

# 计算机是怎么操作的
4+(-5)

0000 0100
1111 1011	0000 0101	取反加一	1111 1010	1111 1011
----------	减法	但是计算机是不会直接减的	这样的加法过程是我们人自己加的
1111 1111	ff
----------  补码
1000 0001


# 狂神思路
4+(-5)

0000 0100
1111 1011
---------- 减法
1111 1111

0000 0100
1111 1011
----------	异或	如果不考虑进位  异或可以直接出结果
1111 1111

0000 0100
1111 1011
----------  与    判断进位  如果与运算结果为0  没有进位
0000 0000

最终结果  1111 1111  HEX ff  DEC -1

乘法 本质是加法 x*y y个x相加

除法 本质是减法 x/y x能减去多少个y

计算机只会做加法

机器语言就是位运算 都是电路来实现的 这就是计算机的底层本质

通过机器语言来实现加法计算器 设计电路

汇编语言

通过指令来代替我们的一些二进制编码

image-20240522154028712

通过汇编指令可以给计算机发一些操作, 然后让计算机执行

编译器的发展 底层的大佬 几乎都是最原始的IDEA

学习C语言的正确方式 用linux学 使用vim编辑器 通过gcc来执行

学习底层需要去使用古老的东西

在学习汇编之前 需要先掌握环境的配置 1. Vc6(程序到汇编的理解) 2. OD 3. 抓包工具 4. 加密解密工具

学汇编不是为了写代码 是为了理解程序的本质

image-20240522155140191

32位 64位 本质架构区别不大 寻址能力增强

可以直接学习32位的汇编

汇编入门 了解汇编和程序的对应关系 程序的本质即可

操作系统内核

image-20240522160127031

通用寄存器

内存

posted @ 2025-02-26 16:55  LYQ学Java  阅读(14)  评论(0)    收藏  举报