调试器在断点处生成int3指令,以便控制转到调试异常处理程序。对于int3,调试器将插入0x cc。他们为什么不插入也表示int3的0x cd 03?如果他们插入0x cd 03而不是0x cc会发生什么?
答案 0 :(得分:2)
英特尔针对该指令的文档为您解答了以下问题:int
/ int3
的第2卷手册中的“说明”部分说:
INT3指令使用一个字节的操作码(CC),用于通过断点异常(#BP)调用调试异常处理程序。 (此一字节形式非常有用,因为它可以替换任何需要断点的指令的第一字节,包括其他一个字节指令,而不会覆盖其他指令。)
有一些1字节的x86指令,例如push reg
。或在16/32位模式inc/dec reg
中。 如果1字节指令是分支目标之前的最后一条指令,则用更长的指令覆盖该指令将破坏可在不到达断点的情况下运行的指令的第一字节。
vm86模式的其他差异在cd 03
的两个字节int 3
编码与1字节的int3
编码之间存在差异,同样在手册。 (大概是为了简化编写从vm86环境外部调试vm86 guest虚拟机的调试器的工作。)
由
INTO
,INT3
或INT1
指令生成的中断与INT n
生成的中断在以下方面有所不同:
- 在虚拟8086模式下不会发生常规IOPL检查。带有任何IOPL值的中断(无故障)。
- 不会发生由虚拟8086模式扩展(VME)启用的中断重定向。中断始终由保护模式处理程序处理。
(这些功能与INT 3的“正常” 2字节操作码
CD03
不相关。Intel和Microsoft汇编程序不会从任何助记符生成CD03
操作码,但是此操作码可以可以通过直接数字代码定义或自我修改代码来创建。)
顺便说一句,在NASM / YASM中,您要做需要将int3
助记符用于1字节编码; int 3
确实会集合到CD 03
GAS将与int $3
相同的int3
组装为0xcc
但是,当然调试器正在使用二进制机器代码,而不是asm源代码。汇编助记符仅适用于在asm源中手动包括断点的情况。 (是的,这是您可以做的事情。大多数调试器都可以通过跳过该指令来使您继续。)