070_二进制到汇编

标签:结束   掌握   none   alt   开机   解密   程序   入门   定义数据   

目录
  • 语言
    • 机器语言
    • 汇编语言
    • 高级语言
    • 反汇编工具:OD
  • 进制-进位计数制
    • 创造自己的进制
    • 进制加密
  • 进制运算
    • 运算的本质就是查数
    • 八进制加法表
    • 八进制乘法表
  • 二进制
    • 为什么要学习理解二进制?
  • 数据宽度
  • 有符号数和无符号数
    • 无符号数规则
    • 有符号数规则
  • 原码反码补码
    • 有符号数的编码规则
    • 计算机存储的是补码
  • 位运算
    • 与运算(and &)
    • 或运算(or |)
    • 异或运算(xor ^)
    • 非运算(单目运算符 not ~)
    • 位运算(移动位)
      • 左移(shl <<)
      • 右移(shr >>)
  • 位运算的加减乘除
    • 计算机只会做加法
    • 加法
    • 减法
  • 汇编语言环境说明
  • 通用寄存器
    • 通用寄存器
    • 计算机如何向寄存器存值
      • mov指令
    • 不同的寄存器
    • 其他寄存器
  • 内存
    • 内存地址
    • 内存如何存值
  • 汇编指令
  • 内存复制
  • 堆栈的指令
  • 汇编如何写函数
  • 堆栈传参
  • 堆栈平衡
  • 外挂

语言

  1. 人和人沟通。
  2. 人和机器沟通。

机器语言

# 我们目前主流的电子计算机
# 状态:0 和 1
# 最早的程序员:穿孔卡带
比如:
加 0000
减 0001
乘 0010
除 0011

汇编语言

  1. 将复杂的机器语言简化成助记符,即汇编语言。
  2. 编译器:将人能够理解的语言转换为机器能够理解的语言。
  3. 汇编语言一般用于底层的编写和单片机。
加 INC -编译器->  0000
减 DEC -编译器->  0001
乘 MUL -编译器->  0010
除 DIV -编译器->  0011

高级语言

  1. 高级语言向人更便于理解的方向演化。
  2. C语言
加 A+B -编译器->  0000
减 A-B -编译器->  0001
乘 A*B -编译器->  0010
除 A/B -编译器->  0011

image.png
image.png

反汇编工具:OD

进制-进位计数制

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

  1. 1进制:一进一,结绳记事。1 1
  2. 2进制:二进一,计算机。0 1
  3. 3进制:三进一。0 1 2
  4. 8进制:八进一。0 1 2 3 4 5 6 7
  5. 10进制:十进一。0 1 2 3 4 5 6 7 8 9
  6. 16进制:十六进一。0 1 2 3 4 5 6 7 8 9 a b c d e f
# 一进制
1
1 1
1 1 1
1 1 1 1
1 1 1 1 1

# 三进制
0    1    2
10   11   12
20   21   22
100  101  102
110  111  112
120  121  122
200  201  202

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

# 一组符号,逢几进几,符号可以随意定义
证明:1 + 1 = 3
创造自己的三进制:0 1 3
0   1   3   10  11  13   30  31  33   100 101 103
# 运算的本质就是查数
0是0位 1是1位 3是2位
1 + 1 = 3 1向后移动1位
3 + 3 = 11 3向后移动2位

创造自己的四进制:0 1 3 a
0   1   3   a  10  11   13  1a  30   31 33 3a
# 运算的本质就是查数
0是0位 1是1位 3是2位 a是3位
1 + 1 = 3 1向后移动1位
3 + 3 = 10 3向后移动2位

创造自己的进制

进制加密

进制运算

运算的本质就是查数

# 运算的本质就是查数
# 八进制
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 31 32 33
# 八进制计算下面的结果
2+3=5 2向后移动3位
2*3=6 2个3位
4+5=11 4向后移动5位
4*5=24 4个5位

八进制加法表

image.png

# 277+333=632

  277
  333  +
------------
  632
  
# 减法的本质是加法
# 237-54=163

  237
   54  -
-----------
  163

八进制乘法表

image.png

276*54=20250

   276
    54  *
---------------
  1370
 1666   +
---------------
 20250
 
# 除法的本质是乘法
234/4=

  234
    4  /
-------------
   47

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

二进制

# 十六进制,二进制的简写
# 十进制    0    1    2    3    4    5    6    7    8    9    10   11   12   13   14   15
# 二进制    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

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

  1. 寄存器、内存、位!底层的每一个位都是有含义的。汇编入门理解的基础!
  2. 汇编高级:了解程序的深层!操作系统的内核!

数据宽度

  1. 计算机:内存!给数据增加数据宽度。
  2. C/C++/Java等强类型语言都需要定义数据的类型,因为计算机底层需要我们给这些数据定义宽度。
位:0 1
字节:8位,0~0xff
字:16位,0~0xffff
双字:32位,0~0xffffffff
  1. 在计算机中,每一个数据都需要给它定义类型。给它定义宽度。在内存中的宽度。

有符号数和无符号数

无符号数规则

  1. 数字是什么,那就是什么。
1 0 0 1  1 0 1 0    十六进制:0x9a    十进制:154

有符号数规则

  1. 最高位是符号位:1(负数) 0(正数)
1 0 0 1  1 0 1 0    负数如何转换为十六进制和十进制?

原码反码补码

有符号数的编码规则

  1. 原码:最高位符号位,对其它的位进行本身绝对值即可。
  2. 反码:
    1. 正数:反码和原码相同。
    2. 负数:符号位一定是1,其余位对原码取反。
  3. 补码:
    1. 正数:补码和原码相同。
    2. 负数:符号位一定是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

# 如果是负数
-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 寄存器,值
计算机存1,存的是1的补码。1->0x00000001
image.png
计算机存-1,存的是-1的补码。-1->0xffffffff
image.png

位运算

与运算(and &)

1011 0001
1101 1000
-------------与运算:都是1,结果才是1
1001 0000

image.png

或运算(or |)

1011 0001
1101 1000
-------------或运算:有一个1,结果就是1
1111 1001

image.png

异或运算(xor ^)

1011 0001
1101 1000
-------------异或运算:不相同,结果就是1
0110 1001

image.png

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

1011 0001
-------------非运算:取反
0100 1110

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

位运算(移动位)

#正数的情况下,对于十进制来说,左移*2,右移/2
0000 0001 1
0000 0010 2
0000 0100 4
0000 1000 8

左移(shl <<)

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

右移(shr >>)

0000 0001
-----------右移:所有二进制位全部右移若干位,低位丢弃,高位由符号位决定(正数补0,负数补1)
0000 0000

位运算的加减乘除

计算机只会做加法

  1. 加法
  2. 减法:x-y,就是x+(-y),本质还是加法。
  3. 乘法:x*y,就是y个x相加,本质还是加法。
  4. 除法:x/y,就是x能减去多少个y,本质就是减法,最终还是加法。

加法

# 计算机是怎么计算的?
# 4+5=?
0000 0100
0000 0101
------------加法:计算机是不会直接加的
0000 1001

# 计算机的实现原理
# 第一步,异或运算(相加):得到,异或运算结果A。
0000 0100
0000 0101
------------ ^
0000 0001 A
# 第二步,与运算(判断进位):得到与运算结果B,判断与运算结果B,如果与运算结果B为0,没有进位,
# 操作结束。最终结果就是异或运算结果A。
0000 0100
0000 0101
------------ &
0000 0100 B
# 第三步,左移(得到进位):与运算结果B不为0,左移一位,得到,进位结果C。
0000 0100 B
------------ <<1
0000 1000 C
# 第四步,异或运算(相加):异或运算结果A和进位结果C进行异或运算,得到,异或运算结果D。
0000 0001 A
0000 1000 C
------------ ^
0000 1001 D
# 第五步,与运算(判断进位):得到与运算结果E,判断与运算结果E,如果与运算结果E为0,没有进位,
# 操作结束。最终结果就是异或运算结果D。如果与运算结果E不为0,有进位,从第三步循环执行。
0000 0001 A
0000 1000 C
------------ &
0000 0000 E
# 所以,最终的结果就是与运算为0时,上一步异或运算的结果。

减法

# 4-5=4+(-5)=?
0000 0101 5
1000 0101 -5 原码
1111 1010 -5 反码
1111 1011 -5 补码

0000 0100
1111 1011
-----------
1111 1111

# 计算机的实现原理
# 第一步,异或运算(相加):得到,异或运算结果A。
0000 0100
1111 1011
------------ ^
1111 1111 A
# 第二步,与运算(判断进位):得到与运算结果B,判断与运算结果B,如果与运算结果B为0,没有进位,
# 操作结束。最终结果就是异或运算结果A。
0000 0100
1111 1011
------------ &
0000 0000 B

汇编语言环境说明

  1. 通过指令来代替二进制操作!
  2. 通过汇编指令,经过编译器编译,然后让计算机执行。
  3. 底层的大佬几乎都用最原始的IDE,因为没有智能的编译器,能更好的查看底层。
  4. 在学汇编之前,需要掌握的环境配置:
    1. VC6(C/C++开发工具,程序到汇编的理解)。
    2. OD(反汇编工具)。
    3. 抓包工具。
    4. 加密解密工具。
  5. 学汇编不是为了写代码,而是为了理解程序的本质。
  6. 32位和64位,本质架构区别不大,只是寻址能力增加。
  7. 汇编入门:了解汇编和程序的对应关系,程序的本质即可!
  8. 下图为OD界面。

image.png

通用寄存器

  1. 寄存器
  2. 存储数据:CPU>内存>硬盘
  3. 32位CPU 8位 16位 32位寄存器
  4. 64位CPU 8位 16位 32位 64位寄存器

通用寄存器

  1. 32位的通用寄存器只有8个。

image.png

  1. 存值的范围:0~FFFFFFFF
  2. 对于二进制来说,存值就是直接修改值。

计算机如何向寄存器存值

mov指令

# 将数字写入寄存器
mov 存的地址,存的值

# 将寄存器A中的值写到寄存器B
mov 存的地址B,存的地址A

image.png

不同的寄存器

FFFFFFFF    FFFF    FF
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位

image.png

其他寄存器

  1. 除了通用寄存器,其他的寄存器每一位都有自己特定的功能,比如:开机,关机等。

内存

  1. 寄存器很小,不够用。所以,把数据放到内存中。
  2. 32位电脑,每个应用程序进程都有4GB的内存空间(虚拟内存)。

image.png

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

内存地址

  1. 存一个数,有两个问题:
    1. 占用的大小:由数据宽度决定。
    2. 存在哪里:由内存地址决定。
  2. 计算机中内存空间很大,每个空间分配一个地址,名字,就是内存地址。

image.png

  1. 这些给内存起的编号,就是我们的内存地址。
  2. 32位的电脑,内存地址就是8个16进制的值。
  3. 每个内存地址都有一个编号,可以通过这些编号向里面存值。

image.png

内存如何存值

  1. 数据宽度:byte word dword
  2. 地址的位置:0xFFFFFFFF
  3. 不是任意的地址都可以写东西的,必须是申请使用的。只有程序申请过的内存地址我们才可以使用。
# 汇编如何向内存中写值
mov 数据宽度 内存地址,值

mov byte/word/dword/qword ptr ds:[0x0019FF70],1

mov byte ptr ds:[0x0019FF70],1

# 传递的值的大小一定要和数据宽度对应。
# 内存地址有多种写法

ds:[0x0019FF70+4] 内存地址偏移
ds:[eax] 寄存器
ds:[eax+4] 寄存器偏移

image.png

汇编指令

内存复制

堆栈的指令

汇编如何写函数

堆栈传参

堆栈平衡

外挂

070_二进制到汇编

标签:结束   掌握   none   alt   开机   解密   程序   入门   定义数据   

原文地址:https://www.cnblogs.com/wl3pb/p/14200450.html

版权声明:完美者 发表于 2021-01-01 12:33:16。
转载请注明:070_二进制到汇编 | 完美导航

暂无评论

暂无评论...