gpt4 book ai didi

c - 为什么 GCC 内联汇编器需要破坏信息,而 MSVC 不需要

转载 作者:太空狗 更新时间:2023-10-29 16:51:09 26 4
gpt4 key购买 nike

我不明白这是怎么回事。

GCC 内联汇编程序很难正确处理,但在标记破坏信息方面非常具体,以便编译器知道您在做什么。

Microsoft Visual C++ 的内联汇编确实很容易使用(它似乎总是 Just Work),但我不知道它对您的代码做出了什么样的保证或假设。

VC++ 会尝试“自动检测”哪些寄存器被破坏了吗?它如何知道寄存器和堆栈指针将如何更改?它有任何假设吗?如果是这样,您如何绕过这些假设?

最佳答案

至于为什么 GCC 不像 MSVC 那样做,有几个原因:

  1. GCC 是一个可重定向的编译器,但汇编语法只是原始文本。为了自动进行破坏检测,GCC 必须解析汇编语言以了解哪些寄存器正在被破坏(包括被其操作码未命名寄存器的指令隐式破坏的寄存器)。这必须适用于所有架构。目前,GCC 不解析汇编语言;在执行 % 替换后,它只是将其粘贴到程序集输出中。思路是生成,避免解析。

  2. 在 GCC 内联汇编语言中,破坏寄存器是异常(exception)而不是规则。原因是它是一种比 MSVC 中的语言更复杂的语言。 GCC 的内联汇编语言为您分配寄存器。因此,您通常不会直接使用 %eax 之类的代码,而是使用 GCC 替换可用寄存器的 %0 之类的代码。 (要做到这一点,编译器不必理解汇编语言!您表达约束以确保 GCC 为适合用法的 %0 替换适当的寄存器。)您仅当您的汇编代码覆盖硬编码寄存器时才需要 clobber,而不是覆盖 GCC 为您分配的输出操作数

请注意,使用 GCC 内联汇编,您不必编写从产生初始值的 C 表达式加载汇编语言操作数或将结果操作数存储到 C 目的地的代码。例如,您只是表示有一个类型为 "r"(寄存器)的输入操作数,它派生自表达式 foo->bar + 1。 GCC 分配寄存器并生成代码以从 foo->bar + 1 加载它,然后用该寄存器的名称替换汇编模板中出现的 %0 .

关于c - 为什么 GCC 内联汇编器需要破坏信息,而 MSVC 不需要,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10504984/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com