首页 > 解决方案 > 写入 EBX 寄存器最终导致程序分段错误

问题描述

当我对它执行任何写操作时,我有一个奇怪的 ebx 寄存器导致段错误的案例。我不知道为什么。ebx 寄存器是否有一些我无法使用的限制?我尝试过使用其他寄存器和这个算法并且它起作用。只有当我使用 ebx 寄存器时才会出现分段错误。我使用的是 x86-32 架构,Intel 语法和 GCC 风格的内联汇编代码。

//code (c)opyright Daniel (Robin) Smith
#include <iostream>

int main ()
{
    int s, i;
    [redacted]

    asm (
            "\n"

           [redacted]

            "       call    series\n"
            "       jmp     finished\n"

            "series:\n"
            "       push    ebp\n"
            "       mov     ebp,esp\n"

            "       mov     ebx,0x1\n"

            [redacted]

            "series_exit:\n"
            "       leave\n"
            "       ret\n"

            "finished:"
            :"=a"(s)
            :"a"(i)
    );
    [redacted]
}

标签: assemblyx86g++cpuinline-assembly

解决方案


在不让编译器知道的情况下,您不得在 gcc 内联汇编中使用任何寄存器。您看到使用 ebx 出现问题的原因是 ebx 是编译器的首选寄存器,用于放置需要保留一段时间的值。但是,您对 ecx 和 edx 的使用也不正确。

有关使用内联汇编以及如何为输入、输出和 clobber 指定寄存器的信息,请参阅https://stackoverflow.com/tags/inline-assembly/info上的链接。(有关 clobbers 的信息位于http://ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html#ss5.3。)

特别是,请参阅https://gcc.gnu.org/wiki/DontUseInlineAsm。您编写的代码最好将其编写为 .s 文件中的常规外联汇编函数,而不是内联汇编。当然,那么您将必须了解调用约定。


推荐阅读