在DebugBreak()中的中断指令int3之前,xchg ax,ax的用途是什么? [英] What's the purpose of xchg ax,ax prior to the break instruction int 3 in DebugBreak()?

查看:0
本文介绍了在DebugBreak()中的中断指令int3之前,xchg ax,ax的用途是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在MASM中,我总是插入独立的Break指令

00007ff7`63141120 cc              int     3
但是,用MSVCDebugBreak函数替换该指令将生成

KERNELBASE!DebugBreak:
00007ff8`6b159b90 6690            xchg    ax,ax
00007ff8`6b159b92 cc              int     3
00007ff8`6b159b93 c3              ret

我很惊讶看到xchg指令在Break指令之前

xchg    ax,ax

从另一篇S.O.文章中注意到:

实际上,xchg ax,ax正是MS对66 90进行反汇编的方式。66岁是 操作数大小覆盖,因此应该在AX而不是EAX上操作。 但是,CPU仍然将其作为NOP执行。使用前缀66 此处使指令的大小为两个字节,通常用于对齐 目的。

MSVC与大多数编译器一样,将函数与16字节边界对齐。

问题该xchg指令的目的是什么?

msvc

推荐答案在函数开头的任何单字节指令之前生成2字节NOP(空函数中的ret除外)。我已经尝试了__halt_enable_disable内部函数,并看到了相同的效果。

显然是用来打补丁的。/hotpatch选项为x86提供了相同的更改,而/hotpatch选项在x64上无法识别。根据/hotpatch文档,这是预期行为(重点是我的):

由于ARM体系结构上的指令始终为两个字节或更长,并且x64编译始终被视为指定了/hotPatch,因此在为这些目标进行编译时不必指定/hotpatch;

因此x64的热补丁支持是无条件的,其结果见DebugBreak实现。

查看此处:https://godbolt.org/z/1G737cErf

Why do Windows functions all begin with a pointless MOV EDI, EDI instruction?关于为什么需要它来打热补丁,请参阅这篇文章。看起来目前的热补丁已经足够智能,可以使用任何两个字节或更多的指令,而不仅仅是MOV EDI, EDI,但它仍然不能使用单字节指令,因为在指令指针指向第二条指令的时刻可能会写入两个字节的向后跳转。

这篇关于在DebugBreak()中的中断指令int3之前,xchg ax,ax的用途是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆