计算机基础汇编

汇编


语言

进制

进制如何运算

二进制

数据宽度

有符号数和无符号数

原码反码补码

位运算

位运算计算

汇编

寄存器

内存

汇编指令

内存复制

堆栈的指令

汇编如何写函数

堆栈传参

堆栈平衡

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

离程序的本质:隔阂!汇编一般用于底层的编写,单片机

C语言

加 A+B INC 编译器-> 0100 0000

减 A-B 0100 1000

乘 A*B 0100 1000 0100 1000

除 A/B 0100 1000 1100 1000

2、进制

二进制? 0 1

学习进制的障碍?

10进制!

人类天然的选择的就是10进制,10个指头,跳出固有思维的方法! “屈指可数”

二级制

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

进制?

1进制:逢1进1,结绳记事,1 1

2进制:逢2进1, 计算机

八进制:逢8进1, 8个符号组成:0 1 2 3 4 5 6 7

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

十六进制:逢16进1, 16个符号组成: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
……

#二进制
0 1 10 11 100 101 111 1000

# 三进制 1~20
十进制:0  1  2 3  4  5  6  7  8  9
三进制:0  1  2 10 11 12 20 21 22 100 101 102 110 111 112

# 七进制 1~20
0  1  2  3  4  5  6
10 11 12 13 14 15 16
20 21 22 23 24 25 26

#一组符号 逢几进几

进制怎样运算?

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

# 八进制计算下面的结果  九九乘法表  加法表!  进制,
277+333 =
276*54 =
237-54 = 
234/4 =

八进制乘法表

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=34
5*5=31 5*6=36 5*7=43
6*6=44 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
# 运算的本质就是就是查数
277
333  +
-------
632

276
 54  *
-------
 1370
1666    +
-------
 20250
 
 
# 减法的本质就是加法   237-54 = 237+(-54)
# 除法的本质  除数乘以那个数最接近结果即可!
-----
234
  4
-----
 47

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

2.1、二进制

计算机使用二进制 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

二进制这么去写很麻烦!二进制能否简写?

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

这就是我们的16进制。

课程上的教学!2进制装换为10进制,然后计算

100 + 101 1001
# 按位 2的零次方+2的1次方+2的2次方+…… = 10进制 ==>二进制
0111 = 7
1
2
4
7

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

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

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

3、数据宽度

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

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

位 0 1

字节 0-0xFF

字 0-0xFFFF

双字 0-0xFFFFFFFF

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

4、有符号数无符号数

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

0 1 0 1 0 1 0 1

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

无符号数规则

1 0 0 1 1 0 1 0    十六进制:0x9A

有符号数规则

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

1 0 0 1 1 0 1 0    如何转换?

5、原码反码补码

编码规则

有符号数的编码规则

编码:最高位符号位,对其他的位进行本身的绝对值即可。

反码:

  • 正数:反码和原码相同
  • 负数:符号位一定是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# 8位# 如果是负数-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 13+5=80 1  2  3  4   50 10 10 11 100 101二进制的标志……2  104  1008  100016 10000

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

寄存器:mov,寄存器,值

6、位运算

计算机现在可以存储所有的数字(整数,浮点数,字符)的,运算!

0 1

位运算?

2*8最高效计算方式

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

与运算(and &)

计算机的本质

1011 00011101 1000-----------   与运算的结果1001 0000

或运算(or |)

1011 00011101 1000----------   或运算的结果1111 1001

异或运算(xor ^)

不一样就是1。

1011 00011101 1000----------   异或运算的结果0110 1001

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

0就是1,1就是0,取反!

1101 1000-----------   非运算的结果0010 0111

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

位运算(移动位)

左移(shl <<):

0000 0001   @  所有二进制为全部左移若干位,高位就丢弃了,低位补00000 0010

右移(shr >>):

0000 0001   @  所有二进制为全部右移若干位,低位就丢弃了,高位就需要补0,1(根据符号位决定)0000 0000int a=6;printf("%d\n",a>>2);
0000 0001  10000 0010  20000 0100  40000 1000  8

7、位运算的加减乘除

计算机只认识0 1

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

4+5?

# 计算机是怎么操作的?0000 01000000 0101----------   (加法,计算机是不会直接加的)0000 1001# 计算机的实现原理# 第一步:异或运算,(如果不考虑进位,异或就可以直接出结果)0000 01000000 0101-----------0000 0001# 第二步:与运算(判断进位!如果与运算结果为0,没有进位。)0000 01000000 0101-----------0000 0100# 第三步:将与运算的结果,左移一位。  0000 1000  # 进位的结果# 第四步:异或!0000 00010000 1000-----------0000 1001# 第五步:与运算(判断进位,如果与运算结果为0,没有进位。)0000 00010000 1000----------0000 0000# 所以最终结果就是与运算结果为0的结果的上一个异或运算。4 + 5 = 90000 0100 + 0000 0101 = 0000 1001 = 9

4-5?

# 计算机是怎么操作的?4+(-5)0000 01001111 1011----------   (减法,计算机是不会直接减的)1111 1111   ff -10000 01001111 1011----------  异或(如果不考虑进位,异或就可以直接出结果)1111 11110000 01001111 1011---------- 与运算  (判断进位,如果与运算结果为0,没有进位。)0000 0000最终结果  1111 1111  16进制 ff  10进制  -1

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

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

结论:计算机只会做加法!

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

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

8、汇编语言环境

通过指令来进行我们的二进制编码。

通过汇编指令可以给计算机发一些操作,然后让计算机执行。编译器的发展,底层的大佬,几乎都是最原始的IDE。

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

学汇编不是为了写代码

而是为了理解程序的本质。

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

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

9、通用寄存器

寄存器:

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

32位CPU 8 16 32

64位CPU 8 16 32 64

通用寄存器可以存储任意的值

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

存值的范围:0~FFFFFFFF

对于二进制来说,直接修改值

计算机如果像寄存器存值。

mov指令

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

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

计算机:计算力!

不同的寄存器

      FFFF  FF   0000 0000
32168位
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位

除了这些通用寄存器之外,那么其他的寄存器每一位都有自己特定的功能!

10、内存

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

平时买的内存条!

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

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

1B(byte)=8b (bit)

1KB=1024B

1MB=1024KB

1GB=1024MB

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

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

内存地址

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

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

这些给内存起的编号,就是我们的内存地址,32位 8个 16进制的值

32位:寻址能力! 4GB 64位!128G

FFFFFFFF+1=100000000,最大的值。

位是怎么限制内存大小的?

100000000 内存地址 * 8 =位:800000000

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

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

64位,绰绰有余!

所以每个内存地址都有一个编号,通过这个编号向里面存值!

内存如何存值?

数据宽度 bit byte word dword

地址的位置:0xFFFFFFFF

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

汇编如何向内存中写值mov 数据宽度 内存地址,1mov btye/word/dword/qword ptr ds:[0x19FF70],6传递的值的大小一定要和宽度相等

内存有多种写法

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

ds:[eax] 寄存器

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

数组[]

ds:[reg+reg*{1,2,4,8}] 数组!

ds:[reg+reg*{1,2,4,8}+4]

猜你喜欢

转载自blog.csdn.net/zhang_0202/article/details/117886186