atoll()函数使用注意事项及分析

atoll是c99标准加入的函数,在编译的时候可能要打开C99标准的编译选项 -std=c99

另外,必须包含stdlib.h头文件,否则会出错。

☞ C程序代码如下所示:

#include <stdio.h>

#include <stdlib.h>  // 声明atoll函数 int main() {     char tempbuf[]="430007020001";     long long unit;

    unit=atoll(tempbuf);     printf("%lld\n", unit);

    return 0; }

编译: gcc -S -o test.s test.c

 

☞ 编译器产生的汇编代码是这样的:

Assembly code

      call    atoll  ;调用atoll。返回值的低32位保存在eax,高32位保存在edx       addl    $16, %esp  调整栈指针,与本题无

      movl    % eax, -32(% ebp)把eax里保存的低32位保存到局部变量unit的低32位

      movl    % edx, -28(% ebp)把edx里保存的高32位保存到局部变量unit的高32位

☞ 而如果把#include <stdlib.h>删掉,也就是不声明atoll函数,编译器产生的汇编代码就变成了这样:

Assembly code

        call    atoll         addl    $16, %esp         cltd ; AT&T汇编里的cltd指令相当于cdq指令,作用是把eax的32位整数扩展为64位,高32位用eax的符号位填充保存到edx

        movl    % eax, -32(% ebp);

        movl    % edx, -28(% ebp);

 

☞ 从汇编代码可以看出:   有atoll声明的时候,编译器知道atoll的返回值是64位,所以直接把edx:eax里面保存的64位返回值赋值给unit。

  而没有atoll声明的时候,编译器认为atoll的返回值是32位,于是多了一条关键的cltd指令。真正调用atoll的时候,atoll也会把返回值保存在edx:eax;但是main里面不知道,通过cltd指令,用eax的扩展把edx里面保存的有用的高32位覆盖掉了。

 

☞ 不添加和添加输出结果对比:

    不添加头文件时,输出510290401,显然是错误的;

    添加头文件后,输出430007020001,正确。

posted @   zxiaocheng  阅读(1513)  评论(0编辑  收藏  举报
编辑推荐:
· .NET 原生驾驭 AI 新基建实战系列:向量数据库的应用与畅想
· 从问题排查到源码分析:ActiveMQ消费端频繁日志刷屏的秘密
· 一次Java后端服务间歇性响应慢的问题排查记录
· dotnet 源代码生成器分析器入门
· ASP.NET Core 模型验证消息的本地化新姿势
阅读排行:
· 从零开始开发一个 MCP Server!
· ThreeJs-16智慧城市项目(重磅以及未来发展ai)
· .NET 原生驾驭 AI 新基建实战系列(一):向量数据库的应用与畅想
· Ai满嘴顺口溜,想考研?浪费我几个小时
· Browser-use 详细介绍&使用文档
历史上的今天:
2015-09-08 Ubuntu 14.04 开机手动开启numlock led
点击右上角即可分享
微信分享提示