C 为什么省略printf的参数会打印垃圾?

C 为什么省略printf的参数会打印垃圾?,c,assembly,x86,printf,C,Assembly,X86,Printf,我通过汇编代码使用printf。我注意到,在下面的示例中,如果我输入预期参数,将打印垃圾 .386 .model flat, c .stack 100h printf PROTO arg1:Ptr Byte, printlist:VARARG .data msg3fmt byte 0Ah,"%s",0Ah,"test output",0Ah,0 .code main proc INVOKE printf, ADDR msg3fmt ret

我通过汇编代码使用printf。我注意到,在下面的示例中,如果我输入预期参数,将打印垃圾

    .386
    .model flat, c
    .stack 100h
printf PROTO arg1:Ptr Byte, printlist:VARARG
    .data
msg3fmt byte 0Ah,"%s",0Ah,"test output",0Ah,0
    .code
main proc
    INVOKE printf, ADDR msg3fmt
    ret
main endp
    end
我的问题是为什么?printf使用的内存地址是否设置为查找参数?既然没有参数通过,为什么要打印任何东西?

标准说

如果
printf()
中的格式说明符数量大于参数数量,则行为未定义

未定义的行为意味着任何事情都可能发生

标准上说

如果
printf()
中的格式说明符数量大于参数数量,则行为未定义


未定义的行为意味着任何事情都可能发生

原因是格式说明符告诉printf它应该接收多少个参数。Printf从堆栈中获取数据;如果您没有为它提供任何数据,那么它将提取堆栈上发生的任何内容并将其视为参数。

原因是格式说明符告诉printf它应该接收多少参数。Printf从堆栈中获取数据;如果您不提供任何数据,它将提取堆栈上发生的任何事件,并将其视为参数。

我问的是发生事件背后的原因,而不是行为未定义的一般答案。@Sonny这就是未定义行为的问题。“为什么”是未定义的。它是。。。未定义的行为。您看到的行为可能有一个原因“在堆栈上找不到参数”,但在ARM上,前几个varargs参数位于寄存器中,因此答案可能是错误的。您可以为varargs和C调用约定设计各种有效的方案。所以,唯一清楚、简洁的说法是,它调用了未定义的行为。@James,但我在问为什么会发生这样的事情。说很多场景都是可能的,并解释特定场景的原因是有区别的。我问的是发生了什么事情背后的原因,而不是行为是未定义的一般答案。@Sonny,这就是未定义的行为。“为什么”是未定义的。它是。。。未定义的行为。您看到的行为可能有一个原因“在堆栈上找不到参数”,但在ARM上,前几个varargs参数位于寄存器中,因此答案可能是错误的。您可以为varargs和C调用约定设计各种有效的方案。所以,唯一清楚、简洁的说法是,它调用了未定义的行为。@James,但我在问为什么会发生这样的事情。说许多场景是可能的和解释特定场景的原因是不同的。