欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

汇编语言学习

程序员文章站 2022-03-13 10:47:11
...

汇编语言

基础准备

进制

每个进制都是独立的,有自己完整的体系,可以不通过转化为十进制进行加减乘除运算(有自己的加法乘法表)
8进制:1,2,3,4,5,6,7,10,11,12,13,14,15,16,17,20
16进制:1,2,3,4,5,6,7,8,9,A,B,C,D,E,F

计算机中的指令,是二进制,简化写成了十六进制,需要记住:
A:1010 B:1011 C:1100 D:1101 E:1110 F:1111

数据宽度

即计算机对数据存储的限制

计算机中常见的数据宽度(容器):

  • 位(BIT) 最小的单位,只能存储一个0或1
  • 字节(Byte)8个位 范围 0~0xFF
  • 字(Word)16个位 范围 0~0xFFFF
  • 双字(Doubleword)32个位 范围 0~0xFFFFFFFF

存储的数据大过最大宽度会被丢弃,从左边开始丢弃。如:用 一个字节存0x1FF,1会被丢弃,变成0xFF

有符号数无符号数

在不同文件中,一串数据代表的含义不同。如在程序中可以是指令,而在文本中是文字。
即依据不同编码规则有不同含义。

无符号数编码规则
正数:无符号数和有符号数编码规则相同,以原码的形式存储在计算机中
负数:存的是补码

原码:第一位为符号位(正数为0,附属为1),其余为数值本身绝对值
反码:正数->反码与原码相同,负数->符号位为1,其他位为原码取反
补码:正数->补码与原码相同,负数->符号位为1,其他位为反码加一

举例说明:-1,数据宽度用一个字节
原码:1000 0001
反码:1111 1110
补码:1111 1111(FF)

一个字节:
无符号数范围:0 1 2 … FF(十进制255) 即0~255
有符号数范围:正数:0 … 7F ; 负数:FF … 80 即-128~-1 0~127
都是存 256个数据

计算机的运算

位运算

符号均选用 C语言中的
与运算&
或运算|
异或^(不同为1)
非运算~
左移<< 去高位低位补0,如1101 1000 左移两位变为 0110 0000
右移>> 去低位高位补0或补符号位,例:

//对于无符号数,右移是去低位高位补 0
//如:1101 0101 -> 0011 0101
unsigned int a = 10;
printf("%d\n",a>>2);
//对于有符号数,右移是去低位高位补符号位
//C语言中int默认为无符号数
//如:1101 0101 -> 1111 0101
int a = 10;
printf("%d\n,a>>2");

加法运算

计算机只能进行位运算,所以加法运算要拆成位运算来进行
加运算:(1)对两数进行异或,对两数进行与运算,
(2)如果与运算有进位,执行(3);否则结果就是异或的结果
(3)把与运算结果左移一位得到一个 新数,把这个数和异或结果 进行(1)

汇编的作用

理解程序怎么运行,对复杂问题可以通过汇编去解决

是寄存器与寄存器、寄存器与内存之间数据的来回流动

关键词:寄存器、内存、指令

寄存器

存储数据用,32位计算机有8位、16位、32位的寄存器

32位通用寄存器,不限定于某块用法
EAX:作返回值 ESP:堆栈(存栈顶的地址)
ECX:计数器 EBP:堆栈(栈底指针)
EDX ESI:串复制的首地址
EBX EDI:串复制的目的地址

EIP:存cpu下一次要执行的指令的地址

指令

MOV:往寄存器或内存里存值 r:通用寄存器 m:内存 imm:立即数
mov指令可以从内存到寄存器、寄存器到内存、寄存器到寄存器、立即数到内存、立即数到寄存器

ADD:相加
SUB:减法 例如:sub a,b 是a-b;把结果存入a
CMP:减法,但是不把结果值存入a;与ZF位一起配合判0
TEST:相当于AND,但不把结果存到前面;与ZF位配合判0
AND:与运算 与完后结果放前面
OR:或运算 或完存前面
XOR:异或运算 结果存前面
NOT:非操作 例:not dword ptr ds:[18FFA0],对该内存的值取反了

movs:从内存到内存
规定从ESI到EDI,ESI要复制的数据地址,EDI存的是目的地址,例:
movs word ptr es:[EDI],word ptr ds:[ESI] 简写MOVSW

STOS指令:将AI/AX/EAX(分别对应1、2、4字节)的值存到[EDI]指定的内存单元

REP:重复执行 依赖ECX,会指定重复几次

JAM:用于修改EIP里的值,后面可跟寄存器 、内存、立即数

CALL:修改EIP,同JAM;并把当前指令(call这个 指令)的下一行地址加到堆栈中(push)

RET:把当前栈顶的值放到EIP里,然后让栈顶地址加4(ESP加4)
即add esp,4 mov eip,[esp-4]

JCC:基于以下标志位的一堆指令
标记寄存器

[外链图片转存失败,源站可能有防盗链机制,建议将汇编语言学习图片保存下来直接上传(img-qoznqqFv-1593498155267)(D:\md\image-20200630134736640.png)]

运算相关的都会影响到标记寄存器
CF:无符号数运算时,产生的结果在最高位发生进位或借位置1,反之清0—>标记无符号数运算是否溢出
PF:如果结果最低位有效字节包含偶数个1位则该位置置1,否则清0—>用于数据传输中检验是否错误或丢失
ZF:运算结果为0置1,反之清0—>用于判断是否为0
SF:存有符号数最高位—>用于判结果为正还是负
OF:溢出为1—>判有符号数运算结果是否溢出

内存

内存地址:内存的编号,大小为32位0x0000 0000~0xFFFF FFFF。
每个内存地址对应一个内存单元大小为一个 字节,故每个进程占4GB

5种把数据存入内存的书写模式

存储模式

数据在内存中储存的方式:
大端模式:数据高位在低位,数据低位在高位
小端模式:数据高位在高位,数据低位在低位

堆栈

给程序分配的一块内存,在用的时候是从大地址开始到小地址(下面说的下一个就是减地址)
ESP:栈指针寄存器,表明程序用到堆栈的哪了

相关指令:
PUSH:ESP值为当前栈顶下一个,并把push后面的值存到ESP指向的内存中(下一个 跟存的数据宽度有关,如word就是上移4个地址,因为每个内存存一个字节,word为4个字节)
可push寄存器、内存、立即数的值
即push指令是一个mov加sub,mov值sub ESP

POP:把当前栈顶的值拿出来,存到寄存器/内存中,并把ESP下移,即add。例:pop EAX,存到了EAX中
即pop指令是一个mov加add

应用

函数

是一系列指令的集合,为了完成某个会重复使用的特定功能

由CALL+执行体+RET构成

可以用寄存器、堆栈存参数,返回值用EAX存

b ESP

POP:把当前栈顶的值拿出来,存到寄存器/内存中,并把ESP下移,即add。例:pop EAX,存到了EAX中
即pop指令是一个mov加add

应用

函数

是一系列指令的集合,为了完成某个会重复使用的特定功能

由CALL+执行体+RET构成

可以用寄存器、堆栈存参数,返回值用EAX存

相关标签: 笔记 反汇编