【问题标题】:Segmentation fault assembly分段故障组装
【发布时间】:2014-04-14 14:05:04
【问题描述】:

我收到以下汇编代码的分段错误,尽管打印由单独的函数处理,但它只是打印出一条消息,所以我很确定我没有在堆栈上为消息分配正确的空间,并且长度。

代码如下:

section .data
    print_msg:      DB "H", 10, 0
    len:            equ $-print_msg 
    print_msg2:     DB "BYE WORLD", 10, 0
    len2:           equ $-print_msg2


section .text

    global main

main:
    push ebp
    mov ebp, esp

    push DWORD len
    push print_msg
    call _write

    push DWORD len2
    push print_msg2
    call _write

    leave
    ret

_write:
    push ebp
    mov ebp, esp   

    push ebx
    mov eax, 4
    mov ebx, 1
    mov ecx, [ebp+8]
    mov edx, [ebp+12]
    int 80h
    pop ebx

    leave 
    ret

【问题讨论】:

  • 不会push print_msg 推送指针,而不是字符?
  • @James:确实会。另一个问题是_write里面的ebp-relative offset是错误的(旧的ebp会在[ebp+0],返回地址会在[ebp+4])。
  • @James Oh 所以指针只有 4 个字节?
  • @Michael 所以你认为我应该摆脱在 _write 中推送 ebp 并解决偏移量。

标签: assembly x86 nasm intel


【解决方案1】:
  1. 您不需要在堆栈上分配任何空间,因为push 会为您完成。
  2. push DWORD [len] 是错误的,因为它试图取消引用 len 这只是一个数字。
  3. mov ecx, [ebp+2]mov edx, [ebp+6] 使用了错误的偏移量,它们应该分别是 +8+12ebp 的堆栈布局为:saved_ebpreturn addressarg1arg2(每个 4 个字节)

像这样:

section .data
    print_msg:      DB "H", 10, 0
    len:            equ $-print_msg

section .text

    global main
main:
    push ebp
    mov ebp, esp
    push DWORD len
    push print_msg
    call _write
    leave
    ret

_write:
    push ebp
    mov ebp, esp
    mov eax, 4
    mov ebx, 1
    mov ecx, [ebp+8]
    mov edx, [ebp+12]
    int 80h
    leave
    ret

PS:C 调用约定要求您应该保留 ebx,因此 _write 函数应该保存并恢复它。

【讨论】:

  • 非常感谢,我明白了,我一直在关注我们需要为要推送到堆栈的项目物理分配空间的教程。
  • 哦,所以我应该将 ebx 压入堆栈,然后在函数外恢复它。
  • 你可以分配空间,但是你应该使用mov来写入这个空间而不是push。确保也为每个参数分配 4 个字节。要保存/恢复ebx,您应该将pushpop 放在_write 内部,我建议分别在mov ebp, esp 之后和leave 之前。
  • 我扩展了我的代码并尝试对恢复的 ebx 值进行排序,我做得对吗,它只是想知道 ebx 恢复。
  • 您仍然有不必要的空间分配,并且您没有将 ebx 保存/恢复放在我告诉您的位置。但它有效:)
猜你喜欢
  • 2018-12-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-19
  • 1970-01-01
相关资源
最近更新 更多