汇编
计算机语言
- 计算机是个傻子,只认识0和1,它没有思考,只是按照我们输入的01跑
- 最早的编程人员,用着穿孔卡带和计算机交流。
- 一串一串的01,让我们怎么也记不住。
- 助记符的产生,是那么的合理。
- 这些助记符就是汇编语言了,一般用于底层,单片机的编写
加:INC
减:DEC
乘:MUL
除:DIV
加密程序:使用自己定义的进制:进制的加密
无论什么进制,本身都是有一套完美的运算体系,我们都可以通过列表的方式将他们计算出来
寄存器、内存、位!底层的每一位都有含义。
数据宽度
计算机:内存!给数据增加宽度
- bit:1位
- Byte:8位
- Word:16位
- DWord:32位
C、C++、java都需要定义数据类型,计算机底层需要我们给这些数据定义宽度
- 位 :0 1
- 字节:0-0xff
- 字:0-0xffff
- 双字:0-0xffffffff
在计算机中,每一个数据都要定义类型,给它定义宽度,在内存中的宽度
- 无符号数:都是数
- 有符号数:最高位是符号位1(负数)、0(正数)
位运算
计算机可以存储所有的数字
- 与(and,&):同为1才为1
- 或(or,|):有一个1取1
- 非(not,!):取反,单目运算符
- 异或(xor,^):不相同则为1
- 左移(shl,<<):高位丢弃,所有位左移
- 右移(shr,>>):地位丢弃,高位根据符号位补相同位
位运算实现加减乘除
基本数学都是建立在加减乘除上
- 计算机内部计算加法的过程
4+5=?
0000 0100
0000 0101
----------(加法,计算机不会加法)
0000 1001
# 计算机只会与或非异或,把加法转换为位运算
# 第一步:异或运算(如果不考虑进位,这里就实现了)
0000 0100
0000 0101
----------(异或)
0000 0001
# 第二步:与运算(判断进位,有进位则为1)
0000 0100
0000 0101
-----------(与)
0000 0100
# 第三步:进位左移(将进位数字与对应位对齐)
0000 0100
-----------(左移)
0000 1000
# 第四步:异或(将进位数字与加法数字异或得到结果)
0000 0001
0000 1000
-----------(异或)
0000 1001
# 第五步:与运算(判断加进位后有没有再进位)
0000 0001
0000 1000
----------(与)
0000 0000
# 如果不为0重复上述过程,最终结果为与运算为0的结果
汇编
- OD界面:
寄存器
储存数据:CPU>内存>硬盘
通用寄存器 :可以存储任何的值
- 32位的通用寄存器只有8个
- 存值范围:0-FFFFFFFF
- 计算机向寄存器中存值:对于二进制来说,直接存值,汇编中用mov指令(mov 地址 数据/地址)
- 寄存器在不同位数计算机中对应的名称
内存
- 寄存器很小,不够用。所以数据要放到内存
- 每个进程都有4G的内存空间
- 程序真正运行的时候才会用到物理内存
1B = 8bit
1kB = 1024B
1MB = 1024kB
1G = 1024MB
计算机中内存地址很多,空间很大。
== 内存地址==:
- 给每个空间分配一个地址
- 32位是8个16进制的值
- 32位寻址能力是4G
内存地址:
- 往内存中写东西:不是任意地址都可以写东西,要申请使用,只有程序申请过的内存地址我们才能使用
# 使用汇编忘内存中写入数据
mov 数据宽度 内存地址,数据
mov byte/word/dword/qword ptr ds:[0019FF74],1
# ptr ds:[0019FF74]:内存地址的一种固定写法
# 传递的值达大小一定要和数据宽度相等
内存地址有很多写法:
- ds:[0019FF74]:直接写地址
- ds:[0019FF74+4]:内存地址偏移
- ds:[eax]:写寄存器地址
- ds:[eax+4]:寄存器偏移
- 数组[]:
- ds:p[reg+reg*{1,2,4,8}]
- ds:p[reg+reg*{1,2,4,8}+4]:偏移