• 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 ", 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,正确。

  • 相关阅读:
    WPF 基于 Azure 的认知服务 情绪分析 语言检测 关键短语提取
    白板类应用的模式交互设计方案
    dotnet Multi-platform App UI 多平台应用 UI 框架简介
    Windows 窗口样式 什么是 WS_EX_NOREDIRECTIONBITMAP 样式
    Windows 对全屏应用的优化
    GitHub Action 新上线 WPF .NET Core 自动构建模板
    为何 WPF 对 vcruntime140 有引用
    用 C# 写脚本 如何输出文件夹内所有文件名
    排序、去重与离散化
    二分
  • 原文地址:https://www.cnblogs.com/zxc2man/p/7493550.html
Copyright © 2020-2023  润新知