1 Star 0 Fork 165

ElonChung / Java-Review

forked from flatfish / Java-Review 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
狂神计算机原理.md 12.80 KB
一键复制 编辑 原始数据 按行查看 历史
icanci 提交于 2020-08-07 14:59 . :tada:更新 汇编原理学习

概述

语言
进制
进制如何运算
二进制
数据宽度
有符号数和无符号数
源码反码补码
位运算
位运算计算
汇编
寄存器
内存
汇编指令
内存复制
堆栈的指令
汇编如何写函数
堆栈传参
堆栈平衡
外挂

语言

人和人沟通,就要使用语言,如果是老外,可能就需要学习老外会的语言,或者老外学习中文。

但是如果是和计算机交流,就要学习计算机的语言。

什么是机器语言
# 我们目前主流的电子计算机
状态表示:0 和 1
# 最早的程序员:穿孔卡带 上面是  0 和 1
# 计算机中只有加法运算
加 1011 0100 
减 1011 0101
乘 1011 0110
除 1011 1110

这些复杂的机器语言,可以简化吗?助记符!这就是汇编语言!

而编译器就是把人能够理解的语言,转化为计算机能够理解的语言(二进制)

加 INC <- 编译器 -> 1011 0100 
减 DEC <- 编译器 -> 1011 0101
乘 MUL <- 编译器 -> 1011 0110
除 DIV <- 编译器 -> 1011 1110

离程序的本质:隔阂!我们不知道底层计算机到底怎么操作的,因为编译器或者编译语言对底层进行了封装

汇编一般用于底层的编写,单片机等等

# 工具下载
https://www.oschina.net/project/tag/332/asm-dev-tools 
https://blog.csdn.net/cto_51/article/details/8827209 
https://cn.bing.com/search?isource=infinity&iname=bing&itype=web&q=汇编开发工具
引用:http://blog.csdn.net/doniexun/article/details/45438457
debuge工具下载:http://www.pcsoft.com.cn/soft/35986.html
masm工具下载http://blog.fishc.com/602.html
ps:6.15在dosbox环境下汇编时回提示确实DOSXNT,用5.0倒是不会
另外,改变dosbox的窗口大小:https://tieba.baidu.com/p/2150370425?red_tag=1911376522
C语言 是汇编的产物
加 A+B <- 编译器 -> 1011 0100 
减 A-B <- 编译器 -> 1011 0101
乘 A*B <- 编译器 -> 1011 0110
除 A/B <- 编译器 -> 1011 1110
进制
二进制? 0 1

学习进制的障碍

10进制

人类天然选择的是十进制,因为是十个指头。跳出固有思维的方法。

二进制

思想:每一种进制都是完美的,都有自己的计算方式

进制

一进制:一进一 结绳计数

二进制:二进一 计算机

八进制:八进一 0 1 2 3 4 5 6 7

十进制:十进一 0 1 2 3 4 5 6 7 8 9

十六进制:十六进一 0 1 2 3 4 5 6 7 8 9 a b c d e f

进制远远没有那么复杂

# 测试

# 一进制 1 - 20
1 1 1 1 1 1 1 1 1 1 1 1
# 三进制
十进制:0 1 2 3  4  5  6  7  8  9   10  11  12  13  14  15  16  17
三进制:0 1 2 10 11 12 20 21 22 100 101 102 110 111 112 120 121 122
# 二进制
二进制:0 1 10 11 100 101 110 111 1000 1001 1010 1011 1100 1101 1110 1111 10000
# 七进制
0 1 2 3 4 5 6 10 11 12 13 14 15 16 20 21 22 23 24 25 26 30、

# 进制就是 一组符号,逢几进几

问题:你真的理解进制了吗?1+1=3 对吗?如果可以使用进制来回答这个问题,那就OK了!

十进制:0 1 2 3 4 5 6 7 8 9

我的十进制: 0 2 1 3 4 a d v s c 可以随便定义

0 1 2 3 4 5 6 7 8 9

0 2 1 3 4 a d v s c

加密解密:程序员,破解程序的人!进制的加密

数字量一大,就可以找到规律破解密码

进制怎么运算
# 八进制计算下面的结果
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 30

# 八进制计算下面的结果 九九乘法表=加法表 进位和计算表
277+333=
277*333=
277-33=
277/34=

计算过程:列出乘法表和加法表即可

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

二进制

计算机使用二进制 0 1 状态!电子!物理极限:摩尔定律!硬操作!追求语言的极限!并发语言!软操作!

量子计算机:(传道)

使用量子计算的机器

传统的计算机:集成电路! 0 1 硅晶片

量子计算机的单位:昆比特 (量子比特) 量子的两态表示

光子:正交偏振方向

磁场:电子的自旋方向

21世纪。计算力,要到尽头了 本质问题

量子计算机!提高计算机的计算力。

量子比特,量子叠加态,量子纠缠,量子并行原理

2019年,Google研究人员展示其最新54比特量子计算机,该计算机只用200秒就可以计算出当前时时间上做大的超级计算机需要1万年的运算。

2020年6月18日。量子体积64位比特

二进制:0 1111
0 1 10 11 100 101 110 111 1000 1001 1010 1011 1100 1101 1110 1111 10000

二进制这么去写很麻烦!二进制的简写!

0 1 2 3 4 5 6 7 8 9 a b c d e f

这就是十六进制

课程上的教学! 二进制转为十进制然后计算

100 + 101 = 1001

# 按位 2的0次方 2的1次方 2的2次方 ... 十进制=>二进制

为什么要学习理解二进制?

寄存器、内存、位!计算机底层的每一个位都是有含义的。汇编理解的的基础!

汇编的高级:了解程序的深层!操作系统的内核!

数据宽度

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

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

位:0 1

字节:0~0xFF

字:0~0xFFFF

双字:0~0xFFFFFFFF

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

有符号数和无符号数

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

0 1 0 1 0 1 0 1

规则:二进制解法增加一个规则

解析一个音频 就是mp3的规则

无符号数规则

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

10011010 十六进制:0x9A 十进制:154

有符号数规则

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

10011010 如何转换
原码反码补码

编码规则

有符号数得编码规则

源码:最高符号位,对齐他的为本身得绝对值即可

反码:

  • 正数:反码和源码相同
  • 负数:符号位一定是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
-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 指令

学习通过直接操作查看是最有效的

位运算

计算机是可以存储所有的数字(整数、浮点数、字符)的,进行运算。

0 1

位运算计算

2-8 最高效的计算方式 2<<3

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

与运算 (and &)

两个都满足,才为 true

···

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

或运算(or |)

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

异或运算(xor ^)

不一样就是1,一样就是 0

1593576642153

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

非运算 (not ~)

0取反是1,1取反是0

1011 0001
------------   非运算
0100 1110

通过这些可以完成加减乘除,使用位运算

位运算(移移动)

左移:(shl <<)

0000 0001 @ 左右的二进制位全部左移若干位,高位就丢弃了,低位补0
0000 0010

有移:(shr >>)

0000 0001 @ 左右的二进制位全部右移若干位,低位就丢弃了,正数高位补0,负数补1
0000 0000
0000 0001 1
0000 0010 2
0000 0100 4
0000 1000 8

二进制、位运算 => 加减乘除

位运算的加减乘除

计算机只认识 0 1

基本数学是建立在 加减乘除。加法

4+5=?

# 计算机是怎么操作的
0000 0100
0000 0101
----------- 加法
0000 1001

# 计算机的实现原理

# 第一步 异或:如果不考虑异或,,就可以直接出结果
0000 0100
0000 0101
------------ 异或
0000 0001
# 第二步 与运算(判断进位,如果运算为0,那就是没有进位)
0000 0100
0000 0101
------------
0000 0100
# 第三步 将与运算的结果左移一位
0000 1000
# 第四步 异或运算
0000 0001
0000 1000
-------------
0000 1001
# 第五步 与运算 (判断进位,如果运算为0,那就是没有进位)
0000 0001
0000 1000
-------------
0000 0000

# 所以最终的结果就是与运算为0的结果的上面的上一个异或运算

4-5=?

# 计算机是怎么操作的
4+(-5) = ?
0000 0100
1111 1011
----------- 加法
1111 1111

0000 0100
1111 1111
----------- 异或
1111 1111

0000 0100 
0000 1011
------------
0000 0000
#最终结果 1111 1111
#符号位又来了

乘:x * y,就是x个y相加,还是加法

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

只要搞定了加法 ,因为计算机只会加法

机器语言就是加减乘除,就是位运算,都是实现电路实现的,这就是计算机最底层的本质。

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

汇编语言

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

通过汇编指令可以给计算机发一些操作,然后让计算机执行。编译器的发展就是封装底层。底层的大佬都是最原始的IDE。C、使用Linux vim gcc

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

学汇编不是为了写代码

理解程序的本质

《汇编语言》 16 位的汇编 32位 64位 (本质架构区别不大,寻址能力增加了)

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

1593586308496

通用寄存器

寄存器:

存储数据:CPU > 内存 > 硬盘

32位CPU 8 16 32

64位CPU 8 16 32 64

通用寄存器

#  32 位的通用寄存器只有8个

1593586565461

存储值的范围:0~FFFFFFFF

计算机如何向寄存器存值,对于二进制来说,直接修改值

计算机如何向寄存器存值

mov指令

mov 存的地址,存的值
mov 存的地址1,存的地址2

可以将数字写到寄存器,可以将寄存器中的值写到寄存器

计算机:计算力

不同的寄存器

32位 16位 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

8位:L低8位,H高8位

除了通用寄存器,其他的的寄存器每一位都有自己的特定功能

内存

寄存器很小,不够用,所以,把数据存放到内存

每个应用都有都有4GB的内存空间。虚拟内存,空头支票。

1593587548156

程序真正运行的时候才会用到物理内存

1B = 8bit

1KB = 1024B

1MB = 1024KB

1GB = 1024MB

4G的内存,4096MB => 计算位为,所以这个可以存储的最大容量

计算机的内存地址很多,空间很大

内存地址

存一个数:占用的大小,数据宽度,存到哪里

计算机内存地址很多,空间很大,每个空间分配一个地址,名字。

给内存取名字就是内存地址

32位:寻址能力

FFFF FFFF+1 = 100000000 最大的值

位怎么限制内存大小的

100000000内存地址 * 8 = 位:800000000

转换为十进制/8:4,294,967,296 字节

按照规则/1024 最终发现就是4GB

随意每个内存地址都有一个编号

1593588036543

内存如何存值?

数据宽度:byte word dword

地址的位置:0xFFFFFFFF

不是任意的地址都是可以写东西的,是申请使用的。只有申请过的内存才可以使用

汇编如何向内存中传值

mov 数据宽度 内存地址,具体的值
mov byte/word/dword/qword ptr ds:[0x19FF10],1
传值的范围不能超过数据宽度

内存地址有多种写法

ds:[0x19FF10+4] 内存地址偏移

ds:[eax] 寄存器

ds:[eax+4] 寄存器偏移

数组[]

未完待续....
1
https://gitee.com/elonchung/Java-Review.git
git@gitee.com:elonchung/Java-Review.git
elonchung
Java-Review
Java-Review
master

搜索帮助