当前位置: 首页 > 知识库问答 >
问题:

如果我不包含头,为什么在调用函数之前清除EAX?

王岳
2023-03-14

在下面的C代码中:

#include <stdio.h>
int main(void){getchar();}

它产生以下ASM:

main:
        push    rbp
        mov     rbp, rsp
                 # no extra instruction here when header is included
        call    getchar
        mov     eax, 0
        pop     rbp
        ret

但是,如果我没有在文件中包含stdio.h,那么它仍然会编译,但会添加看起来像是随机的mov eax,0指令:

这里是编译器资源管理器:https://godbolt.org/z/3ftcss。这仅仅是“未定义行为”的一部分,还是有特殊的原因将调用getchar之前的指令添加到那里?

共有1个答案

牛兴安
2023-03-14

如果没有标头,gcc在您使用它时会提供getchar的隐式声明,就像您以前声明的那样

int getchar();

(C标准的旧版本保证了这种行为。当前版本使使用以前未声明的html" target="_blank">函数成为未定义的行为,但gcc仍将旧行为作为扩展提供。)

此声明没有提供有关getchar所需的参数类型的信息。(请记住,与C++不同的是,带有()的声明不是将函数声明为不带参数,而是将函数声明为带未指定的参数,让程序员知道函数需要什么,并传递正确数量和类型的参数。)对于编译器所知道的,它甚至可以是变量的,并且根据x86-64 SysV ABI,变量函数在al中期望用于传入参数的向量寄存器的数量。这里没有使用向量寄存器,因此编译器在调用之前将al设置为0。(实际上将RAX全部归零会更有效一些,所以它会这样做。)

 类似资料:
  • 我见过类似的问题,但他们仍然没有意义,我的猿类大脑。 这里有一个例子。如果我在名为的头文件中声明了一个函数:并且在文件中声明了一个函数:。我在另一个文件(例如)中看到过这样的人,它只包含头,它只有声明(里面没有代码),而不包含带有代码的。但令我震惊的是,当他们调用中的函数时,它使用了中的代码并打印“hello”。怎么做?当我只包含了文件时,它如何打印在文件中添加的“hello”,而它只是一个声明,

  • 我试图在RESTAPI中对登录和安全性进行单元测试,所以我尝试尽可能地模拟现实生活中的请求序列。 我的第一个要求是: (请参见pastebin上的完整类)。 我尝试在这里获取cookie,以便以后能够使用收到的CSRF令牌登录,但是数组是空的! 然而,如果我运行我的应用程序并调用 我确实得到了一个Set Cookie头,可以稍后使用该Cookie(和CSRF令牌)进行身份验证。 所以问题是:如何让

  • 这里,当我返回一个箭头函数insted时,它不起作用: 我知道箭头函数是松散的,这就是为什么我在这里尝试在括号中返回它。没有他们也不行。

  • 问题内容: 我想清除并更改给定URL上的输入值。我使用的js不会执行任何操作,也不会导致任何错误。为什么会发生这种情况,我该如何解决? 问题答案: 一个可能且可能的答案是,在尝试清除的元素之前,您还有另一个具有相同名称的元素。 请检查html并检查是否找到多个元素,然后采用第一个。 另外,您可以使用css选择器,例如:

  • 看js 的原生库函数,比如:parseInt(),为什么库函数只写了函数名和参数和返回类型, 没有写 {要操作的内容体} 呢?