汇编
学习汇编的原因
开发者角度 优化代码
硬件
控制器,运算器,存储器,输入设备,输出设备。中央处理器是对信息进行高速运算处理的主要部件,其处理速度可达每秒几亿次以上操作。存储器用于存储程序、数据和文件,常由快速的主存储器(容量可达数百兆字节,甚至数G字节)和慢速海量辅助存储器(容量可达数十G或数百G以上)组成。
各种输入输出外部设备是人机间的信息转换器,由输入-输出控制系统管理外部设备与主存储器(中央处理器)之间的信息交换。
软件
系统软件,支撑软件,应用软件。系统软件由操作系统、实用程序、编译程序等组成。操作系统实施对各种软硬件资源的管理控制。实用程序是为方便用户所设,如文本编辑等。编译程序的功能是把用户用汇编语言或某种高级语言所编写的程序,翻译成机器可执行的机器语言程序。
支撑软件有接口软件、工具软件、环境数据库等,它能支持用机的环境,提供软件研制工具。支援软件也可认为是系统软件的一部分。应用软件是用户按其需要自行编写的专用程序,它借助系统软件和支援软件来运行,是软件系统的最外层
CPU中有
Pc 程序计数器
Alu 运算器
寄存器文件
SRAM 高速缓存 又称三级缓存。缓存的出现表示可以做更复杂的程序。
存储器不具备传输和存储功能,CPU一般从内存取数据比磁盘取数据块1000万倍。CPU从L1(高速缓存区)取数据比内存块100倍。
DMA主线 直接内存访问 。告诉磁盘直接传送到内存
因为高速缓存存储器出现,所以可以使用汇编指令优化。提高效率。
c语言为了兼容,所以很多设备没有对应的代码可以表示。为了解决C语言解决不了的问题,所以有时候会使用汇编语言 。
一般高级语言和汇编语言一起使用来做到取长补短。
寄存器 8086/8088 cpu外部设备(i/o)
Ax bx cx dx si di sp bp
Add base count date sourse dest stack point base point
做加法 放基址 计数 数据 原位置 目标位置 栈指针 基址指针
Doc系统debug
一般我们运行cmd是因为Cmd模拟doc系统
以下是 Debug 命令列表:
常用的 * 标记
* ? 显示 Debug 命令列表。(帮助)
* Chcp 修改代码页(选择字符集)936中文
* a 汇编 8086/8087/8088 记忆码。 (编辑汇编语言)
d 显示部分内存的内容。 (查看内存)
c 比较内存的两个部分。
* e 从指定地址开始,将数据输入到内存。 (修改)
* f 使用指定值填充一段内存。
g 运行在内存中的可执行文件。
h 执行十六进制运算。
i 显示来自特定端口的 1 字节值。
l 将文件或磁盘扇区内容加载到内存。
m 复制内存块中的内容
* /n 为 l 或 w 命令指定文件,或者指定正在测试的文件的参数。 (命名)
o 向输出端口发送 1 个字节的值。
* p 执行循环、重复的字符串指令、软件中断或子例程。 (相当于vsF10)
* q 停止 Debug 会话。 (退出)
* r 显示或改变一个或多个寄存器。 (查看寄存器)
s 在部分内存中搜索一个或多个字节值的模式。
* t 执行一条指令,然后显示所有寄存器的内容、所有标志的状态和 Debug 下一步要执行的指令的解码形式。 (单步调试相当于vsF11)
* u 反汇编字节并显示相应的原语句。
* w 将被测试文件写入磁盘。 (写文件)
写文件大小和寄存器中的cx有关,写文件前要先给字节数大小
xa 分配扩展内存。
xd 释放扩展内存。
xm 映射扩展内存页。
xs 显示扩展内存的状态。
系统调用
为了使程序员方便调用各个常用设备,所以常用设备设置系统功能调用(又称系统调用,有名api) cd 21 《==》int 21 表示系统调用
文件名 .com表示文件第一句就是执行代码段,没有格式,双击可以运行。
CPU通电会启动Dois来检测硬件程序,有问题提醒用户,没有问题从7c00开始执行代码(即操作系统程序开始)
8086内部结构
8个通用寄存器
1个指令指针寄存器
1个标志寄存器
4个段寄存器
标志寄存器
CF:进位标志位。在无符号运算时,记录了运算结果的最高有效位向更高位的进位值或从更高位借位,产生进位或借位时CF=1,否则CF=0;
PF:奇偶标志位。相关指令执行后结果所有bit中1的个数为偶数,那么PF=1,1的个数为奇数则PF=0;
AF:辅助进位标志位。运算过程中看最后四位,不论长度为多少。最后四位向前有进位或者借位,AF=1,否则AF=0;
ZF:零标志位。相关指令执行后结果为0那么ZF=1,结果不为0则ZF=0;
SF:符号标志位。相关指令执行后结果为负那么SF=1,结果非负数则SF=0;
TF:调试标志位。当TF=1时,处理器每次只执行一条指令,即单步执行;
IF:中断允许标志位。它用来控制8086是否允许接收外部中断请求。若IF=1,8086能响应外部中断,反之则屏蔽外部中断;
DF:方向标志位。在串处理指令中,每次操作后,如果DF=0,si、di递增,如果DF=1,si、di递减;注意此处DF的值是由程序员进行设定的 cld命令是将DF设置为0,std命令是将DF设置为1;
OF:溢出标志位。记录了有符号运算的结果是否发生了溢出,如果发生溢出OF=1,如果没有OF=0;
溢出漏洞实例
Void chek (char* buf size_t count ,size_t size)
{
Char* result = malloc( count * size )
(这里有漏洞 n位和n 位相乘得出结果最多为2n 结果只能保留size_t 的大小)
If(res == NULL)
Return;
For(size_t i = 0;i < count;i++)
{
Memcpy( result + i * size , buf + i*size , size);
}
}
数据信息的表达单位
计算机中信息的单位
二进制位Bit:存储一位二进制数:0或1
字节Byte:8个二进制位,D7~D0
字Word:16位,2个字节,D15~D0
双字DWord:32位,4个字节,D31~D0
最低有效位LSB:数据的最低位,D0位
最高有效位MSB:数据的最高位,对应字节、字、双字分别指D7、D15、D31位
数据的地址对齐
字单元安排在偶地址
双字单元安排在模4地址
对于不对齐地址的数据,处理器访问时,需要额外的访问存储器时间
物理地址和逻辑地址
物理地址 == xxxxxh
逻辑地址 == 段基地址 : 段内偏移地址
段基地址 安排在模16的地方这样就可以访问到FFFF0H的地方 省去低四位
物理地址和逻辑地址的转换
段地址后面加一个0 加上段偏移地址即 1234:0010 ->12340 + 0010 = 12350
段寄存器和逻辑段
4个16位段寄存器
CS(代码段)指明代码段的起始地址
SS(堆栈段)指明堆栈段的起始地址
DS(数据段)指明数据段的起始地址
ES(附加段)指明附加段的起始地址
每个段寄存器用来确定一个逻辑段的起始地址,每种逻辑段均有各自的用途
计算机通过CS : IP寄存器来控制指令序列的执行流程
段寄存器的发明并不只为了地址访问,更是一种设计,将所有的段合并可以实现连接完成多人开发
程序中
Mov ax ,[1000] 从DS + 1000的位置取出数据
段超越
CS:(这里填需要超越的段不填默认数据段)
Mov ax ,[1000] 强制告诉编译器在cs中1000的位置取数据