windows – 使用单字节指令开始x64函数是否合法?
根据masm的macamd64.inc,rex_push_reg,
但是,我无法找到任何表达此文件的文件.这是真的?它在哪里记录?为什么会这样?
该声明的执行部分似乎是“呼叫标准” – 它标准是什么?这个笑话可能是旧的,但它仍然很贴切:关于标准的好处是有很多可供选择.
在这种情况下,由于您说的是MASM,我们可以假设目标平台是Windows,因此假设是Windows 64-bit calling convention,而不是官方AMD64规范中的内容.但是,和你一样,我找不到任何符合这一要求的东西. 但是,我认为此评论所指的是Microsoft的内部标准,旨在允许对系统二进制文件进行热修补. “热修补”是指在内存中动态修补二进制文件的能力 – 例如.应用系统更新 – 无需重新启动. 这项工作的最低要求是在每个函数的开头都有一个2字节短JMP指令的空间. (注意,短跳转只允许执行从当前指令指针的-128到127字节的任何位置传递,但这足以分支到一个长跳转,然后跳转到更新提供的补丁功能.实际上,跳转指令被修补到函数之间的填充.) 因此,函数不能以1字节指令开始,因为热补丁可能会导致指令指针指向指令的中间. (考虑多线程竞争条件.)所以规则是,如果你想用一个通常只有1个字节的PUSH RBP这样的序言指令开始一个函数,你需要添加一个1字节的REX前缀.这个不必要的REX前缀被CPU忽略,并且基本上起到1字节NOP的作用. 在32位版本中,通过2字节指令MOV EDI,EDI提供热修补.这会将EDI寄存器复制到自身而不会影响标志,因此它实际上是一个NOP. 对于32位版本,您必须专门将 那么,为什么要制定这个复杂的规则而不是让编译器在每个函数的开头插入一个2字节的NOP,就像在32位版本中一样?好吧,我不能肯定地说,但我可以推测.一个问题是MOV EDI,EDI不是x64上的NOP,因为它隐含地将RDI寄存器的高32位归零.你必须选择一个不同的指令作为NOP,一旦你完成了这个,你不妨重新考虑整个业务.其次,在那里使用NOP会产生(轻微)性能成本,并且由于长模式下的大多数指令长度至少为2个字节,因此在通常需要的指令时要求无意义的NOP指令似乎不值得.只有少数例外情况就足够了. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- windows-server-2008 – Perfmon – 无法启动数据收集器集
- windows-server-2008 – Windows 2008忽略了Gratuitous ARP
- 使用anaconda安装tensorflow (windows10环境)
- 使用WIndows PowerShell 1.0或2.0来评估可执行文件的性能
- winapi – “@”在以Windows字体名称作为前缀时的含义是什么
- windows – C#catch kill命令
- 我要禁用Windows XP中的CTRL ALT DEL在我的ANSI-C代码?
- windows – 在AD网络上模拟打印机
- windows – SFTP服务器dmz vs trusted
- windows-8 – 如何做UI自动化的Metro风格的应用程序?