当前位置: 首页 > 编程 > 正文

一.DEBUG调试器命令 1.1 U命令(反汇编) -U:表示从当前地址开始反汇编 -U后面加上地址表示从该地 […]

一.DEBUG调试器命令

1.1 U命令(反汇编)

  • -U:表示从当前地址开始反汇编

  • -U后面加上地址表示从该地址处开始反汇编,例如 U 200 就是从当前数据段开始往后偏移200处开始反汇编.

1.2 D命令(显示数据)

  • D:表示显示数据(16进制),相当于VS调试中的查看内存.

  • -D后面加上地址表示从改地址开始显示数据,例如 D 200 就是从当前数据段开始往后偏移200处开始显示数据.

1.3 R命令(查看寄存器)

  • -R:表示当前寄存器的内容.

第一行:通用寄存器
AX - Add 累加器 | BX - Base 基址寄存器 | CX - Count 计数器 | DX - Data 数据寄存器
SP - 堆栈指针寄存器(栈顶) | BP - 基址指针寄存器(桟底) | SI - 源变址寄存器 | DI - 目标变址寄存器

第二行前半部分:特殊寄存器
DS - 数据段起始地址
ES - 附加段起始地址
SS - 堆栈段起始地址
CS - 代码段起始地址
IP - 指令寄存器,存放即将要执行的指令地址

第二行后半部分:标志寄存器

第三行:即将要执行的指令

  • -R (寄存器) 表示修改这个寄存器内容,如 -R AX

1.4 E命令(修改数据并保存)

  • -E 200 表示修改当前数据段,偏移位200的位置的数据.连续修改需要在每个字节中间加上空格.

1.5 G命令(断点执行命令)

  • -G 表示从IP寄存器取出地址并执行.如果后面加上地址则表示执行到该地址处.

1.6 A命令(汇编命令)

  • -A 写入汇编命令

  • -A 后加上地址,表示将汇编代码写入该地址处.(默认小尾方式)

1.7 P命令(单步步过)

  • -P 类似VS中的F10,单步步过

1.8 T命令(单步步入)

  • -P 类似VS中的F11,单步步入.(在没有函数的情况下,与P命令单步步过没有区别)

1.9 保存文件

  • N命令(为该文件取名字)
  • W命令(将数据写入磁盘,CX寄存器的值为写入的字节数)

  • 后缀名.COM文件,不同于Win32编程中的面向对象COM,这个COM表示段空间不超过64K,默认其实地址偏移为0x100.

二.8086指令系统

2.1 什么是指令系统?

  • 计算机的指令系统就是该计算机能够执行的全部指令集合.每种CPU都有自己支持的指令集.

  • 指令集与品牌无关,与架构有关.(ARM | X86)

  • 为了通用,尽量不要用最新指令.新指令出来很多年后才会被普及使用.

2.2 8086内部结构

  1. 从内存中通过外部总线取出指令,放入指令队列缓冲器.通过执行部分控制电路执行指令.
  2. ALU - 运算器.

现代CPU执行的三个步骤
1. 取指令
2. 解释
3. 执行

2.3 8086的寄存器组

2.3.1 8086的16位通用寄存器

  • AX - Add 累加器 - 使用额度最高,用于算术,逻辑运算以及外设传送信息等.
  • BX - Base 基址寄存器 - 常用存放存储地址.
  • CX - Count 计数器 - 循环和串操作等指令中隐含计数器
  • DX - Data 数据寄存器 - 内存地址/端口号
  • SP - 堆栈指针寄存器 - 栈顶
  • BP - 基址指针寄存器 - 桟底
  • SI - 源变址寄存器 - 类似内存拷贝中源数据
  • DI - 目的变址寄存器 - 类似内存拷贝中目标数据

2.3.2 指令指针寄存器

  • 指令指针寄存器IP.指示代码段中指令的偏移地址.
  • 与代码段寄存器CS联用,确定下一条指令的物理地址. CS:IP
  • IP是一个专用寄存器.

2.3.3 标志寄存器FLAG

名称 标志 标志位1 标志位0 备注
溢出标志 OF (Over flow flag) OV(溢出) NV(没溢出) 常用
方向标志 DF (Direction flag) DN(反向) UP(正向)
中断标志 IF (Interrupt flag) EI(允许中断) DI(禁止中断)
符号标志 SF (Sign flag) NG(为负) PL(为正) 常用
零标志 ZF (Zero flag) ZR(结果为0) NZ(结果非0) 常用
辅助标志 AF (Auxiliary carry flag) AC(低4四位进位) NA(低4字节没进位)
奇偶标志 PF (Parity flag) PE(低8位1的个数为偶数) PO(低8位1的个数为奇数)
进位标志 CF (Carry flag) CY(有进位或借位) NC(无进位或借位) 常用

2.3.3.1 进位标志CF

  • 当运算结果的最高有效位有进位(加法)或者借位(减法)时,进位标志位置1,即CF = 1;否则CF = 0.

  • 3AH + 7CH = B6H(10110110),没有进位: CF = 0

  • AAH + 7CH = (1)26H(100100110),有进位:CF = 1

  • CF = 0 = NC(没进位) | CF = 1 = CY(有进位)

2.3.3.2 零标志ZF

  • 若运算结果为0,则ZF = 1, 否则ZF = 0

  • ZF 为 1 表示结果是 0.

  • 3AH + 7CH = B6H,结果不是零:ZF = 0

  • 84H + 7CH = (1)00H,结果是零:ZF = 1

  • ZF = 0 = NZ(零) | ZF = 1 = ZR(非零)

2.3.3.3 符号标志SF

  • 运算结果最高位为1,则SF = 1(负数); 否则 SF = 0(正数).

  • 有符号数据用最高有效位表示数据的符号,所以,最高有效位就是符号标志的状态.

  • 3AH + 7CH = B6H, 最高位D7 = 1: SF = 1

  • 84H + 7CH = (1)00H, 最高位D7 = 0: SF = 0

  • SF = 1 = NG(负数) | SF = 0 = PL(正数)

2.3.3.4 奇偶标志PF

  • 当运算结果最低字节中'1'的个数为零或者偶数时,PF = 1(零或偶数);否则 PF = 0(奇数);

  • PF标志仅反应最低8位中"1"的个数是偶或奇,即使是进行16位字操作.

  • 7000H + 10FFH = 80FFH = 1000000011111111B ; 低8位结果有8个1,是偶数:PF =1

  • PF = 1 = PE(零或偶数) | PF = 0 = PO(奇数)

2.3.3.5 溢出标志OF

  • 在进行有符号数运算时,如果超过了机器所能表示的范围称为溢出.什么是机器所能表示的范围呢?比如说,指令运算的结果用8位寄存器或者内存单元来存放,比如 add al,3,那么对于8位的有符号数据,机器所能表示的范围就是-128~127.同理,对于16位有符号数据,机器所能表示的范围是-32768~32767.如果运算结果超出了机器所能表达的范围,将产生溢出.

  • 溢出,只是针对有符号运算而言.如下例:

mov al,98
add al,99

执行后将会产生溢出.因为 add,al,99进行的有符号运算是:
(al) = (al) + 99 = 98 + 99 = 197
而197超出了机器所能表示的8位有符号数运算范围:-128~127.

  • 标志寄存器的第11位是OF,溢出标志位.一般情况下,OF记录了有符号数运算的结果是否发生溢出.如果发生溢出,OF=1;如果没有,OF=0.
  • 溢出超过表达范围,进位没有超过表达范围.

  • 判断溢出:只有两个相同符号相加(包括不同符号相减),而运算结果的符号与原数据符号相反时,产生溢出.

  • 如果将你将他看出无符号数,就不要看这个标志位,因为无符号数不可能溢出.FF + FF = (1)FE.

  • 7FFFH + 2710H = A70FH (32767 + 10000 = 42767)产生溢出.(若为有符号数-32767 ~32767)

  • OF = 1 = OV(溢出) | OF = 0 = NV(没溢出)

2.3.3.6 辅助进位标志AF

  • 运算时D3位(低半字节(低4字节))有进位或借位时,AF = 1; 否则AF = 0.

  • 这个标志主要由处理器内部使用,用于十进制算术运算调整指令中,用户一般不必关心.

  • 3AH + 7CH = B6H ,D3有进位:AF = 1.

  • 8FH + 81H = 110H (0000 0000 1000 1111B + 0000 0000 1000 0001B = 0000 0001 0001 0000B)

  • AF = 1 = AC(进位) | AF = 0 = NA(没进位)

2.3.3.7 方向标志DF

  • 用于串操作(类似内存拷贝)指令中,控制地址的变化方向:

  • 设置DF = 0,存储器地址自动增加(正向拷贝)

  • 设置DF = 1,存储器地址自动减少(反向拷贝)

  • 要配合变址寄存器 SI 和 DI 使用.

  • CLD 指令复位方向标志: DF = 0

  • STD 指令置位方向标志: DF = 1

  • DF = 1 = DN(反向拷贝) | DF = 0 = UP(正向拷贝)

2.3.3.8 中断允许标志IF

什么是中断?
1. 如同现在取快递,来了短信通知快递到了,放下手中事物(中断)去收快递.
2. CPU需要知道键盘什么时候按下,然后通知操作系统,操作系统中断去处理按键.(早期:死循环读键盘扫描码,判断按键按下)
3. CPU如果如果发现IF标志位为0,就不收取中断信号.(IF标志位控制CPU接不接收中断信号)
4. 死循环修改IF标志位为0.可屏蔽中断...(反反调试,有时候调试器也需要中断信号.)


  • 用于控制外部可屏蔽中端是否可以被处理器响应:

  • 设置IF = 1,则允许中断

  • 设置IF = 0,则禁止中断

  • CLI指令复位中断标志:IF = 0

  • STI指令置位中断标志:IF = 1

  • IF = 1 = EI(允许中断) | IF = 0 = DI(禁止中断)

2.3.3.9 陷阱标志TF

  • 用于控制处理器进入单步操作方式:

  • 设置TF = 0,处理器正常工作;

  • 设置TF = 1,处理器单步执行指令.

  • 单步执行指令 - 处理器在每条指令执行结束时,便产生一个编号为1的内部中断,这种内部中断称为单步中断,所以TF也称为单步标志

  • 利用单步中断可对程序进行逐条指令的调试(单步调试).

  • 每次单步后此标志位会清零.

  • 这种逐条指令调试程序的方法就是单步调试.

  • 死循环修改此标志,可以反调试.

三.指令手册

  • 之前买CPU时可向Intel申请白皮书,如今只有PDF下载.

3.1 指令手册术语(ADD指令示例)

  • Clocks - 指令周期

  • rea/reg8/reg16 - 通用寄存器/8位寄存器/16位寄存器

  • mem/mem8/mem16 - 表示一个内存地址/8位内存地址/16位内存地址

  • immed - 立即数

  • accum - AX寄存器,累加器

  • EA - 寻址方式

3.2 指令格式

  • 如第一条. 04表示 : ADD AL,imm8 (AL = AL + IMM8)

  • 如第二条. 05表示 : ADD AX,imm16 (AX = AX + IMM16)

四.16汇编Hello World

4.1 DOS功能调用


* AH - 功能(API)编号.(1双字节最多256个功能)

  • 我们要显示字符串,需要用到09这个功能号,得把09存入AH.

  • 而字符串地址为 DS:DX. 数据段默认为DS.于是我们把 "Hello World"这个字符串的偏移位置存入DX即可.

  • INT 21 调用功能

  • 注意, 以 $ 这个符号结束字符串.

4.2 向内存写入字符串

4.3 写文件

4.4 运行

本文固定链接: https://blog.050k.com/?p=160 | LseKit's Blog
标签:,

02_16汇编_寄存器:等您坐沙发呢!

发表评论

快捷键:Ctrl+Enter