汇编的简单学习

汇编的由来

​ 本来的时候,计算机只能识别010101数字,然后可以通过二极管的开和关表示0、1,但是这样和计算机交互非常困难,

所以就将所有操作简化成助记词,也就是汇编语言

#  加法 INC -->  经过汇编编译器 转换成计算机01指令 
#  减法 DEC
#  乘法 MUL
#  除法 DIV
进制

进制?

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

2进制:二进一, 0 1 0 11 计算机

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

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

16进制: 16进一 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~20
1   2  10
11  12 20
21  22 100
101 102 110
111 112 120
121 122 1000
1001 1002

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


# 为什么还有十六进制?
二进制			  十六进制
0001 0000		 10
1100 0011		 C3
也就是说,如果将一个二进制数从右往左,分成4 比特为一组的形式,分别将每一组的值转换成十六进制数,
就可以得到这个二进制数所对应的十六进制数。

十六进制  3    F    8
二进制  0011 1111  1000

正如前面所说的,从事计算机的学习和研究(包括咱们马上就要进行的汇编语言程序设计),不可避免地要与二进制数打交道,而且有时还必须针对其中某些比特进行特殊处理。这个时候,如果想保留二进制数的直观性,同时还要求写起来简短,十六进制数是最好的选择

1 + 1 = 3

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

我的十进制:0 2 4 6 8 a w c q k

进制加密!!!

进制怎么运算
# 八进制计算下面的结果
2 + 3 =
2 * 3 = 
4 * 5 = 

# 运算的本质就是查数
# 以前的加减法和乘除法是逢十进一
# 那么在八进制下,就是逢八进一


 347
  74  +
-------- 
 423
二进制

计算机使用二进制 0 1 物理极限:摩尔定律

量子计算机

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

量子计算机的单位:昆比特。(量子比特!)量子的两个状态

光子:正交偏振方向

磁场:电子的自旋方向

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

量子比特、量子叠加态、量子纠缠、

回到电子计算机

数据宽度

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

位 0 1

字节 0-0xFF

字 0-0xFFFF

双字 0-0xFFFFFFFF

有符号数、无符号数

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

0 1 0 1 0 1 0 1

规则

解析一个音频:MP3解码格式,不同的规则

给二进制解码,给一个规则

无符号数规则

你这数字是什么就是什么

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

-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

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

计算机底层,存储负数是存它的补码的

F = 1111

位运算

与运算(and &)

# 两个都为1,结果为1

1001  0011
1010  1101   &
--------------
1000  0001

或运算(or | )

# 只要有1个1,结果为1

1001  0011
1010  1101   |
--------------
1011  1111

异或运算( xor ^ )

# 不一样就是1

1001  0011
1010  1101   ^
--------------
0111  1110

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

# 0就是1  1就是0

1010  1101   ~
--------------
0101  0010

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

位运算(移动位 )

左移( shl <<)

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

右移(shr >>)

1 >> 1
0000 0001
所有二进制全部右移若干位,高位补0,低位丢弃(根据符号决定)
0000 0000

int a = 10;
printf("%d\n",a>>2)
位运算的加减乘除
4 + 5
# 计算机的实现原理  加法

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

#第二步,与运算(判断进位,如果与运算结果为0,就说明没有进位)
0000 0100
0000 0101   &
--------------
0000 0100

# 第三步,讲与运算的结果向左移一位, 0000 1000 #进位的结果
因为进位了,所以都要左移一位

# 第四步,再异或一次,第一次异或结果和与运算的结果异或
0000 0001
0000 1000   ^
-------------
0000 1001  

# 第五步,将上一步操作再与运算一次,判断是否有进位
0000 0001
0000 1000   &
-------------
0000 0000

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


#   4 - 5
#  也就是  4 + (-5)
#计算机是没有减法的

0000 0100
1111 1011   ^
--------------  #异或,不考虑进位,可直接出结果
1111 1111  #  ff=-1


0000 0100
1111 1011   &
--------------  # 判断进位,如果与运算结果为0,就说明没有进位
0000 0000


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

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

除法:x / y :也就是x能减去多少个y,还是加法

汇编语言

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

学习汇编之前,先掌握环境

1.VC6

2.OD

在这里插入图片描述

通用寄存器

寄存器

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

32位CPU 8 16 32

64位CPU 8 16 32 64

通用寄存器

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iwepTP5L-1636074768308)(C:\Users\16242\AppData\Roaming\Typora\typora-user-images\image-20211011090530326.png)]

存值的范围:0 ~~ FFFF FFFF

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

计算机如果向寄存器存值·

mov指令

# 可以在寄存器存值
mov 存的地址,存的数
# 可以将寄存器的值存入寄存器
mov 要存的地址1,存数的地址
#  F8执行

不同的寄存器

F*8		 FFFF     FF
32168位
EAX		 AX		  AL	  
ECX		 CX		  CL
EDX		 DX		  DL
EBX		 BX		  BL
ESP		 SP		  AH
ENP		 NP  	  CH
ESI		 SI		  DH
EDI		 DI		  BH

8位:L第八位,H高八位

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

内存

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

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

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

内存地址

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

地址很多,

所以每个内存地址都有一个编号,可以通过这个编号进行存值

在这里插入图片描述

内存如何存值?

数据宽度: byte word dword

地址的位置:0xFFFFFFFF

不是任意的地址都可以写东西,需要申请使用

# 汇编如何向内存写值
mov 数据宽度 内存地址,1
#例子
mov byte ptr ds:[0x19FF70],1

内存地址有多种写法

ds:[0x19FF70+4] 偏移量

ds:[eax] 将寄存器中值写入内存

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

数组[]

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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Oak Coffee

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值