Assembly 在malloc(程序集NASM x86)之后调用get

Assembly 在malloc(程序集NASM x86)之后调用get,assembly,x86,nasm,Assembly,X86,Nasm,在使用malloc(也是C库的)分配内存后,我试图调用C库的“get”函数,但我一直遇到分段错误,我不知道为什么!! 我知道堆栈有问题,但我不知道是什么! 代码如下: section .rodata LC0: DB "The number is: %i", 10, 0 ; string LC1: DB "Allocation failed!!!", 10, 0 ; string section .data section .bss stack_size:

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

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

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

push ecx
call gets
pop ecx
如果该
ecx
应该是读取字符串的缓冲区,那么您没有将其设置为任何有用的值。这几乎可以肯定是为什么你会出现内存故障

malloc
返回的缓冲区被放入
eax
,而不是
ecx
。我怀疑这就是您希望在
获取
参数时推送的内容


如果您分配的内存不在希望将
gets
中的字符放入的位置,则需要先将
ecx
初始化到其他缓冲区,然后再将其推入。

我不是要推eax,我想推ecx作为缓冲区,我知道malloc的返回地址在eax中,我准备将结果移动到stack_size变量中。另外,初始化ecx也无助于解决问题-分段错误。@yair,按ecx作为确切的缓冲区。实际上,您没有将
ecx
设置为任何值
gets
需要一个缓冲区,您似乎给了它一些随机值,因此出现了故障。您希望将从
gets
中获取的字符确切放置在何处(您刚才调用的缓冲区似乎是最符合逻辑的位置)?在按下之前,您需要初始化
ecx
。我想将它们放入eax中,然后将它们复制到我指定的缓冲区中(调用C函数的返回值总是放在eax中)。即使我用“mov ECX,0”或诸如此类的东西初始化ECX,它仍然会给出错误。@yair:好的,
malloc
中的内存地址在
eax
中,而不是
ECX
。因此,在调用
get
之前,需要按下
eax
。如前所述,您没有显式地将
ecx
设置为任何值,因此它可能是一些不适合传递给
get
的任意值。而将ecx设置为0也无济于事,这是空指针。您需要将其设置为指向某种类型的有效缓冲区。如果我在开始时删除所有部分,那么:push ecx call gets pop ecx工作正常,我甚至可以打印结果,如果ecx不作为缓冲区处理,您如何解释它?