【问题标题】:Segmentation fault, but why ? Ubuntu Intel分段错误,但为什么? Ubuntu 英特尔
【发布时间】:2015-11-15 14:52:13
【问题描述】:

我是汇编编程的新手,我遇到了一个问题,我收到了这个错误:

程序收到信号SIGSEGV,分段错误。循环下一个字符 () 在 XXX.s:136 136 movq %rax, (%r11)

代码如下:

getText:

    xorq    %r11, %r11
    xorq    %rax, %rax  
    xorq    %r10, %r10
    xorq    %r9, %r9
    movq    %rsi, %r10
    movq    %rdi, %r11

LoopNextChar:
    cmpq    $0, %r10
    je  returnTxt

    cmpq    $63, buffInPtr
    je  inImage

    sub     $8, %rsp
    call    getChar
    add $8, %rsp

    cmpq    $0, %rax
    je  returnTxt

    movq    %rax, (%r11)
    incq    %r11
    incq    %r9
    incq    %r10
    jmp     LoopNextChar


returnTxt:  
    movq    %r9, %rax
    ret
//

getChar:
    movq    $buffInPtr,%r10
    movq    $buffIn,%r9
    xorq    %rax,%rax
    cmpq    $63,(%r10)
    je  inImage
    addq    (%r10),%r9
    movzbq  (%r9),%rax
    addq    $1,%r10
    ret

【问题讨论】:

  • 学习使用调试器并注释您的代码,尤其是在您希望其他人提供帮助时。至于故障,显然r11 的地址无效,这可能是因为您有溢出或调用者传入了错误的参数开始。 PS:您将 64 位写入仅递增 1 的指针也很可疑(但这并没有错)。
  • 所以这可能是由代码的其他部分引起的,没有使用 rax ?
  • 由于rax 用于退出循环,如果它得到一个错误的值,它可能不会及时退出循环,因此增加r11 直到它溢出缓冲区。 buffInPtr 没有在任何地方调整也很可疑。但是,您还没有显示完整的代码。
  • buffInPtr 正在调整 addq $1,%r10...
  • 这不会改变buffInPtr 本身,除非你把它写回去,但你没有。所以cmpq $63, buffInPtr 总是看到相同的不变值。已经使用调试器单步执行代码。

标签: assembly segmentation-fault x86-64


【解决方案1】:

问题是 buffInPtr,它从未增加...为了解决这个问题,我写了 incq buffInPtr 而不是 addq $1, %r10

【讨论】:

  • 不是递增内存操作数,而是将该变量保存在寄存器中。更改比较和东西以使用该寄存器。 x86-64 有 15 个 GP 寄存器。将循环变量保留在内存中很愚蠢,因为inc [mem] 有 6 个周期的延迟,将您的循环限制为每 6 个周期运行一次迭代。请参阅agner.org/optimize,了解如何编写运行速度快的好 asm。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-08-11
  • 1970-01-01
  • 2021-04-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多