zoukankan      html  css  js  c++  java
  • 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,正确。

  • 相关阅读:
    php7 安装mssql 扩展
    CentOS 7使用yum安装MYSQL
    PLSQL Developer 连接Linux 下Oracle的安装与配置
    VNC 在ubuntu desktop下只显示空白桌面
    Spring Boot 学习系列(11)—tomcat参数配置建
    Spring Boot 学习系列(10)—SpringBoot+JSP的使
    Spring Boot 学习系列(09)—自定义Bean的顺序加载
    Spring Boot 学习系列(08)—自定义servlet、filter及listener
    Spring Boot 学习系列(07)—properties文件读取
    Spring Boot 学习系列(06)—采用log4j2记录日志
  • 原文地址:https://www.cnblogs.com/zxc2man/p/7493550.html
Copyright © 2011-2022 走看看