一个数字二进制是四位,每个数字或字母代表一个四位二进制
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.