一个数字二进制是四位,每个数字或字母代表一个四位二进制
16 进制是二进制简写形式
位是最小单位,一个字节(0-ff)八个位,字 16 位,双字32
无符号数的编码规则:里面的值是什么就存储什么
有符号数 正数编码规则
最高位是 1 是负数(补码形式) 如果 0 就是正数(与无符号数编码规则一样)
与运算
或运算
只要有 1 就是 1 汇编符号 or
异或运算
不一样的时候才为 1 汇编符号 xor
非运算
0 是 1 1 是 0 汇编符号 not
单目
左移
各二进位全部左移若干位,高位丢弃,低位补 0 汇编符号shl
右移
- 异或运算
不考虑进位异或运算与加的结果一样
- 判断是否有进位
俩一进位,一个零和一个一不进位
- 继续异或
把立即数写到内存
内存必须有地址,地址的宽度是 32 位的,每个位对应的是一个字节
Mov:命令 mov byte ptr ds:[出现的地址],1
内存明确告诉宽度 byte 一个字节 保证两边宽度一样
把寄存器的数写到内存
8 个 32 位寄存器
加法
减法
与运算
或运算
异或运算
非指令
指定 ESI EDI(两个地址)寄存器
执行一次地址自动加字节(地址 DF 位为 0 加,为 1 时减)
Byte 把al 的放进 EDI WORD 对应 ax Dword 对应 EAX重复执行指令
Ecx 后面为 16 进制堆栈就是一块内存
和数据结构的堆栈无关
ESP 栈指针寄存器 存储当前堆栈用到哪 从大地址往小地址用 占用完要改 ESP 地址
或者用 PUSH 指令(可以用寄存器)
Push 等 于 mov 加 sub Pop 等 于 mov 加 add
修改 EIP 相关指令
EIP cpu 下次执行的地址
Mov 不能修改 eip 寄存器
Jmp 指令仅仅修改 EIP 的值
Call 指令按 f7
Call 修改 eip,把当前指令的下一个地址存到堆栈里 esp的值变化
Retn 指令
把当前栈顶的值放进 EIP 里然后栈顶指针加四调试
F2 设置断点
Call 用 F7 跟
汇编指令的函数 函数是指令的集合
通常不用 jmp
如果使用十个参数(堆栈传参)
堆栈传参执行完可以在外面单独加一行代码使ESP 回到
地址(外平栈)Ret 跟字节数回到
(内平栈)
改程序
- 修改内存
- 用别的程序直接调用
ESP 寻址弊端:栈顶受指令影响,复杂函数不易操作, 有时候需要修正
Pop 倒着存出
EBP 寻址(ebp 栈底不变,更好寻址):push ebp ESP
会向上移动然后再给 esp 赋值
<br />![](https://cdn.nlark.com/yuque/0/2021/jpeg/21361730/1640935590064-c502ccde-72c1-464c-90d0-de8e18dcf75c.jpeg#)![](https://cdn.nlark.com/yuque/0/2021/jpeg/21361730/1640935590378-2af5ace1-736f-4f37-8a3e-313c9f7355a5.jpeg#)<br /> <br /> <br />![](https://cdn.nlark.com/yuque/0/2021/jpeg/21361730/1640935590574-b10a5d6d-2cf8-4074-8dd2-a3e2ad1a04aa.jpeg#)
函数执行提升一段堆栈,用完将回来
标准寄存器(运算相关的 指令会影响):EFLAGS
CF 通常标识无符号数运算的时候是否发生溢出 C位看高位
PF 奇偶校验位 P 位看最低位 校验数据有没有丢失或修改
AF 辅助进位标志
CMP:相当与 SUB 但是相减的结果不存到寄存器中
TEST:相当于 AND 指令,也不保存在寄存器只影响标志寄存器
看符号位是 0 还是 1
Jcc 指令:根据标志寄存器状态是否修改 EIP
lea 指令可以用来将一个内存地址直接赋给目的操作数
cmp(compare)指令进行比较两个操作数的大小
例:cmp oprd1,oprd2
为第一个操作减去第二个操作数,但不影响第两个操作数的值,它影响 flag 的
CF,ZF,OF,AF,PF.