【问题标题】:calling gets after malloc (assembly NASM x86)在 malloc 之后调用(程序集 NASM x86)
【发布时间】:2014-04-25 13:23:58
【问题描述】:

在使用 malloc(也是 C 库的)分配内存后,我试图调用 C 库的“gets”函数,但我不断收到分段错误,我不知道为什么!! 我知道堆栈有问题,但我不知道是什么! 这是代码:

section .rodata
LC0:
    DB  "The number is: %i", 10, 0  ;  string

LC1:
    DB  "Allocation failed!!!", 10, 0   ;  string


section .data

section .bss

stack_size:
    RESB    20

section .text
    align 16
    global main
    extern printf
    extern malloc
    extern gets
    link_size EQU 5

_start:
    jmp main 

main:

    mov dword edi, link_size
    push edi
    call malloc
    mov dword [stack_size], eax

    test eax,eax
    jz fail_exit

    add esp,4

    push ecx
    call gets
    pop ecx

    ret

fail_exit:
    push LC1
    call printf
    add esp,4

【问题讨论】:

    标签: assembly x86 nasm


    【解决方案1】:

    暂且不说 gets 是一个非常不安全的函数,即使您正确使用它(无法防止缓冲区溢出),您的直接问题就在这里:

    push ecx
    call gets
    pop ecx
    

    如果ecx 应该是读取字符串的缓冲区,那么您还没有将它设置为任何有用的东西。这几乎肯定是您遇到内存故障的原因。

    malloc 返回的缓冲区被放入eax,而不是ecx。我怀疑这就是您想要作为 gets 参数推送的内容。

    如果您分配的内存不是您要放置gets 中的字符的位置,您需要在推送之前将ecx 初始化为其他缓冲区。

    【讨论】:

    • 我不是要推 eax,我想推 ecx 作为缓冲区,我知道 malloc 的返回地址在 eax 中,我已经将结果移动到我的 stack_size 变量中。此外,初始化 ecx 也无助于解决问题 - 分段错误。
    • @yair,将ecx 推送为 what 缓冲区。您实际上没有将ecx 设置为任何内容。 gets 需要一个缓冲区,而您似乎给了它一些随机值,因此出现了故障。您究竟希望将从gets 获得的字符放置在哪里(您刚刚分配的缓冲区似乎是最合乎逻辑的位置)?在推送之前,您需要将 ecx 初始化为该值。
    • 我想将它们放入 eax,然后将它们复制到我 malloc'ed 的缓冲区中。 (调用 C 函数的返回值总是放在 EAX 中)。即使我用“mov ecx,0”之类的东西来灌输ECX,它仍然会出错。
    • @yair: 好的,来自malloc 的内存地址在eax不是 ecx。所以你需要在调用gets之前推送eax。正如我所说,您没有将ecx 明确设置为任何值,因此它可能是一些不适合传递给gets 的任意值。并且将ecx 设置为 0 也无济于事,这就是空指针。您需要将其设置为指向某种有效的缓冲区。
    • 如果我一开始就删除所有部分,那么: push ecx call gets pop ecx 工作正常,我什至可以打印结果,如果 ECX 不被视为开始?
    猜你喜欢
    • 2013-05-14
    • 2015-09-20
    • 1970-01-01
    • 1970-01-01
    • 2015-09-22
    • 2018-02-04
    • 2011-12-22
    • 2013-09-17
    • 1970-01-01
    相关资源
    最近更新 更多