课程安排
16位汇编(8)
32位汇编(8)
调试器(4)
PE(10)
壳(4)
shellcode(4)
逆向(20)
MFC原理(7)
16位汇编课程安排
- 汇编基础和debug使用
- 寻址方式
- 传送指令和算术指令
- 乘除和位移指令
- 串操作和跳转指令
- 函数
- 宏汇 ```cpp 1+0=1 0 1+1=0 1 0+1=1 0 0+0=0 0
结果: left ^ right 进位: left & right
3 5 3(4+1) = 3*4 +3 = 3<<2 + 3
```cpp
mov reg, reg
mov reg, imm;(立即数,常数)
mov ax, 5566
mov al, 78
add reg1, reg2
add reg, imm;
add ax, bx; ax = ax+bx
add ax, 1234; ax = ax + 1234
;add 2354, ax; 错误语句
sub
- 了解硬件运行机制
- 了解微机系统硬件组成
- 了解计算机系统组成
- 8086cpu组织架构
debug使用
问题
- 为什么计算机的操作数据的单位是二进制?
- 总线
- cpu有8位数据/地址线,ram是个256bute的存储器。
- debug的使用
配置DosBox
可以对其修改来配置dosbox
但是这样每次都要重新去执行之前那两句指令,我们可以配置一下,使得每次加载直接就提前执行好那两句
mount c: D:\DosBox\cr40_asm16
set path=c:
也可以直接用visual studio code
下载对应扩展,可以旋转对应语言
右击可以打开DOS环境
还可以切换一下
这里我们用一下jsdos观察一下(最终还是dosbox使用舒服)
- debug的使用
启用dos模式,启用debug,然后输入?可以查询一些信息
- u[range] 反编译 [range]=[startaddr][endaddr]或[startaddr|num]
如果之前没有执行过u指令,它会从ip指向的地方开始
之前有的话就接着上面的
-u
-u 100
-u 100 111
-u 100 l 11
- a 汇编
- r[reg] 可以查看寄存器或者修改寄存器,后面加寄存器就是修改,不加就是查看
- d[range]
示例:
-d
-d 110
-d 110 150
-d 110 l 16
- e addr 修改内存
示例:(从110处开始修改 以空格分开 不想改的以空格跳过 回车结束)
若不想一个个这样更改,也可以按照以下格式更改
e addr val1[逗号|空格 val12 逗号|空格val3…]
也可以直接写字符串进入内存
- t单步步过
- p单步执行
- g
- 写文件(n,cx,w)
示例:
要略过 Windows 2000 文件系统并直接加载特定的扇区,请使用以下语法:
l address drive start number
(上面的文件winhex查不到写入内容)
改为: w 200
标志寄存器
- 进位和溢出
- 进位针对的是无符号数运算,溢出针对的是有符号运算
- 当看成无符号数,则关注CF标志,看成有符号数,则关注OF位
**
- 符号标志SF
- 奇偶标志位
- 辅助进位标志位AF
作业:
**
写代码测试各个条件标志位,推理逻辑图文表示提交。
- 测试:CF,ZF,PF
mov ah,ox80
add al,al
这里,寄存器AL自己和自己做加法运算,并且最高位置1,而产生进位。结果是进位被丢弃,AL中最终变为零。
进位的产生使得 CF=1,同时:ZF=0,PF=0;
- 测试OF,CF,SF
mov ah,0x70
add ah,ah
首先,本次计算结果,以二进制表示为0111 0000B + 0111 0000B = 1110 0000B;
最高位并没有进位,故CF=0;
其次,从无符号数的角度上来看,112+112=224<255,并没有超出一个字节所能容纳的上限255,结果正确;
但是,从有符号运算的角度来看,即112+112=-32,两个正数相加得到一个负数,显然是错误的。在这种情况下,OF=1;错误的原因是,两个正数112相加,得到的结果应该是224,但是224超出了一个字节所能表示的有符号数的范围 -128~127;所以破坏了符号位,使得结果变成了(-32);
由上诉总结,结果是负数,最高位的标志位为1,因此SF=1;
- 测试AF标志位
xor al,al
mov al,08
add al,al
这里,加法结果AX=0x10,由于al低四位相加产生半进位,因此将标志位AF置1