【问题标题】:Segmentation fault: 11 Assembly OSX分段错误:11 汇编 OSX
【发布时间】:2016-03-29 01:36:43
【问题描述】:

您好,我还是使用 gcc 编译器的汇编语言的新手,现在我正在研究函数。 我的程序向用户询问 4 个int 值,将这些值存储在寄存器eaxebxecxedx 中,然后调用一个函数进行除法(ebx/eax)。我在除法后存储“d”的值,因为据我了解idiv 使用edx 来存储残差。然后它减去 (eax-ecx) 并乘以 (eax*edx),然后返回寄存器 eax 内的值。出于某种原因,我遇到了分段错误:11。 这是我的代码:

#include <stdio.h>

int a, b, c, d;

int main (void)
{
    printf("Dame a: ");
    scanf("%d", &a);
    printf("Dame b: ");
    scanf("%d", &b);

    printf("Dame c: ");
    scanf("%d", &c);

    printf("Dame d: ");
    scanf("%d", &d);

    __asm(    ".intel_syntax noprefix;"
              "xor eax, eax;"
              "mov eax, dword ptr [_a];" 
              "xor ebx, ebx;"
              "mov ebx, dword ptr [_b];"
              "xor ecx, ecx;"
              "mov ecx, dword ptr [_c];"
              "Call fun1;"
              "mov dword ptr [_a], eax;"


              "fun1:  xor edx, edx;"
              "idiv ebx;"
              "sub eax, ecx;"
              "mov edx, dword ptr [_d];"
              "imul eax, edx;"
              "ret;"

              ".att_syntax");

    printf("%d\n", a);
}

是不是跟指针错误有关?

【问题讨论】:

  • 没有从 C 代码调用的函数。这看起来像是错误集成的汇编代码。你认为这如何执行?您没有将 C 变量正确传递给汇编程序代码,没有列出任何破坏者等。请阅读必须如何使用内联汇编程序。
  • 另外,在 inline asm 中切换语法是个坏主意。如果您想要 intel 语法 asm,请使用 gcc -masm=intel。 PS:你的执行落入fun1,然后第二次命中的ret将退出main(如果你幸运,否则它会崩溃)。
  • 嗨 Jester 感谢您的回答,我知道在内联 asm 中切换语法是不好的做法,由于某种原因,如果我不这样做,我会得到 64 不支持 32 位绝对寻址-位模式错误。
  • 我很惊讶即使使用 intel 语法也能编译。如果您真的要为 64 位编译,那么除了所有其他评论之外,我可能会使用 RIP 寻址。例如,我将dword ptr [_a] 编码为[rip+_a]。在 AT&T 语法中,_a(%rip)

标签: c macos gcc assembly x86


【解决方案1】:

除了在 cmets 中指出的其他错误之外,这里还有一个重大问题:

         "mov ecx, dword ptr [_c];"
          "Call fun1;"
          "mov dword ptr [_a], eax;"


          "fun1:  xor edx, edx;"
          "idiv ebx;"
          "sub eax, ecx;"
          "mov edx, dword ptr [_d];"
          "imul eax, edx;"
          "ret;"

考虑程序流程。您的 C 代码属于此汇编代码。汇编代码调用自己的内部函数(不是问题),然后返回调用之前的指令......仍然没有问题。一个值被移动到 EAX... 然后你通过你的函数返回。这太糟糕了。

通过使用ret,您将绕过整个 C 函数结语。这意味着堆栈没有正确清理,堆栈也没有恢复。这几乎肯定会导致崩溃。

【讨论】:

    猜你喜欢
    • 2012-04-24
    • 2013-09-17
    • 1970-01-01
    • 1970-01-01
    • 2015-06-07
    • 1970-01-01
    • 1970-01-01
    • 2015-10-04
    • 1970-01-01
    相关资源
    最近更新 更多