32位机器如何处理大于2^32的数字?

2023-12-22

I am trying to understand how calculations involving numbers greater than 232 happen on a 32 bit machine.

C code

$ cat size.c
#include<stdio.h>
#include<math.h>

int main() {

    printf ("max unsigned long long = %llu\n",
    (unsigned long long)(pow(2, 64) - 1));
}
$

海湾合作委员会输出

$ gcc size.c -o size
$ ./size
max unsigned long long = 18446744073709551615
$

对应的汇编代码

$ gcc -S size.c -O3
$ cat size.s
    .file   "size.c"
    .section    .rodata.str1.4,"aMS",@progbits,1
    .align 4
.LC0:
    .string "max unsigned long long = %llu\n"
    .text
    .p2align 4,,15
.globl main
    .type   main, @function
main:
    pushl   %ebp
    movl    %esp, %ebp
    andl    $-16, %esp
    subl    $16, %esp
    movl    $-1, 8(%esp)   #1
    movl    $-1, 12(%esp)  #2
    movl    $.LC0, 4(%esp) #3
    movl    $1, (%esp)     #4
    call    __printf_chk
    leave
    ret
    .size   main, .-main
    .ident  "GCC: (Ubuntu 4.4.3-4ubuntu5) 4.4.3"
    .section    .note.GNU-stack,"",@progbits
$

第 1 - 4 行到底发生了什么?

这是汇编级别的某种字符串连接吗?


__printf_chk是一个包装器printf它检查堆栈溢出,并采用一个额外的第一个参数,一个标志(例如,参见here http://refspecs.freestandards.org/LSB_4.0.0/LSB-Core-generic/LSB-Core-generic/libc---printf-chk-1.html.)

pow(2, 64) - 1已优化为0xffffffffffffffff因为参数是常量。

根据通常的调用约定,第一个参数__printf_chk() (int flag)是堆栈上的 32 位值(位于%esp在当时的call操作说明)。下一个论点,const char * format,是一个 32 位指针(堆栈上的下一个 32 位字,即位于%esp+4)。正在打印的 64 位数量占据接下来的两个 32 位字(在%esp+8 and %esp+12):

pushl   %ebp                 ; prologue
movl    %esp, %ebp           ; prologue
andl    $-16, %esp           ; align stack pointer
subl    $16, %esp            ; reserve bytes for stack frame
movl    $-1, 8(%esp)   #1    ; store low half of 64-bit argument (a constant) to stack
movl    $-1, 12(%esp)  #2    ; store high half of 64-bit argument (a constant) to stack
movl    $.LC0, 4(%esp) #3    ; store address of format string to stack
movl    $1, (%esp)     #4    ; store "flag" argument to __printf_chk to stack
call    __printf_chk         ; call routine
leave                        ; epilogue
ret                          ; epilogue

编译器有效地重写了这个:

printf("max unsigned long long = %llu\n", (unsigned long long)(pow(2, 64) - 1));

...进入这个:

__printf_chk(1, "max unsigned long long = %llu\n", 0xffffffffffffffffULL);

...并且在运行时,调用的堆栈布局如下所示(将堆栈显示为 32 位字,地址从图的底部向上递增):

        :                 :
        :     Stack       :
        :                 :
        +-----------------+
%esp+12 |      0xffffffff | \ 
        +-----------------+  } <-------------------------------------.
%esp+8  |      0xffffffff | /                                        |
        +-----------------+                                          |
%esp+4  |address of string| <---------------.                        |
        +-----------------+                 |                        |
%esp    |               1 | <--.            |                        |
        +-----------------+    |            |                        |
                  __printf_chk(1, "max unsigned long long = %llu\n", |
                                                    0xffffffffffffffffULL);
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

32位机器如何处理大于2^32的数字? 的相关文章

随机推荐

  • 仅比较日期和月份与mysql中的日期字段

    如何仅比较日期和月份与mysql中的日期字段 例如 我在一张表中有一个日期 2014 07 10 同样 另一个日期2000 07 10在另一张桌子上 我只想比较日期字段上的日期和月份是否相等 我尝试过这种格式 但我无法得到答案 select
  • 如何使用 'in' 运算符返回 0 而不是 null

    我有三张桌子 文本 行中的文本 trigram 所有文本行的trigram text trigram 文本行包含的三元组 中间表 当我执行这个时 select count coalesce text id 0 text id from te
  • 带优先级队列的 Dijkstra 算法

    在我的 Dijkstra 算法的实现中 我有 1 个包含所有节点的数组和 1 个包含所有节点的优先级队列 每当一个节点出队时 我都会用新的距离和它的来源更新所有相邻节点 这样我就可以回溯路径 优先级队列中的节点将更新为新距离 数组中的节点将
  • 包“@angular/cli”不是依赖项

    当我尝试运行命令时出现以下错误 ng update angular cli angular core allow dirty Repository is not clean Update changes will be mixed with
  • 如何对 BSD 套接字进行单元测试 [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我正在使用 BSD 套接字在 Ubuntu 中编写基于服务器 客户端的 C 应用程序 我使用 Google C 测试框架作为我的单元测
  • Mailjet Vars 空白数组引发错误

    array low price low stock goods gt 在我的邮件模板中 for item in var low price low stock goods tr td item good name td td item va
  • MySQL:您的 SQL 语法错误 |限制 0, 25

    我不明白这个错误 请大家帮助我 为什么我收到这个错误 我的查询有问题吗 这是错误 1064 你的 SQL 语法有错误 检查与您的 MySQL 服务器版本相对应的手册 了解要使用的正确语法 第 7 行 LIMIT 0 25 附近 这是我的查询
  • 如何将 Pandas DF 中的列表转换为字符串?

    我有一个熊猫数据框 其中一列包含一个列表 我希望该列是单个字符串 例如我的清单 one two three 应该简单地是 one two three df col df col astype str apply lambda x join
  • 使用 React js Modal 的动态内容

    我想使用 React js 模态获取动态内容我正在使用包react responsive modal 首先我通过地图渲染所有帖子 现在我希望当我单击单个帖子时 模式应该弹出并仅显示该特定帖子的标题和正文 现在我不知道如何在模态中获取单个帖子
  • 有没有办法将 C# 序列化对象读取到 Python 中?

    我有一个包含 C 序列化对象的二进制文件 我可以用 python 读取内容 但得到的结果类似于 T x00 x00 x00Test Jobs GenerateJobRequest POC Server xca x02 xa2 x02 t x
  • 去虚拟化非最终方法

    假设我有一个如下所示的类设置 class A public virtual void foo printf default implementation n class B public A public void foo override
  • CNContactViewController 取消按钮不起作用

    我正在尝试使用内置的新联系人 UI 但使用取消按钮时出现意外行为 下面的代码可以运行并调用新的联系人屏幕 但取消按钮只会清除屏幕条目 而不会从新的联系人屏幕中取消 在内置联系人应用程序中 点击取消将返回到联系人列表屏幕 我想要取消按钮来关闭
  • CSS将一个正方形分成4个三角形

    我目前正在尝试将一个正方形变成 4 个大小相等且具有悬停事件的三角形 我正在创建这样的三角形 right left top bottom position relative width 26px right before position
  • 升级到 Django 1.11 后,append_slash 不再起作用

    在 Django 1 9 和 Python 3 4 中 默认的 APPEND SLASH 工作正常 即我可以输入 localhost 8000 ideatree videos 并且会添加尾部斜杠 升级到 Django 1 11 和 Pyth
  • Java/zip:为什么 .jar 文件的创建是不确定的?

    我从未真正研究过它 但现在我意识到我无法轻松构建两个相同的 jar 文件 我的意思是 如果我构建两次 而不更改任何内容 我会得到完全相同的大小 但校验和不同 jar 所以我很快进行了一些测试 基本上解压 排序 n k 5然后diff ing
  • mutate_impl(.data,dots)评估错误:找不到对象

    我有一些工作代码 我必须更新 R 并再次安装所有软件包 当我尝试再次运行代码时遇到了困难 这是一个玩具示例 工作代码 get cyl column mtcars gt dplyr select cyl add 1 to all numeri
  • 将 div 居中对齐

    我想漂浮一个div到中心 是否可以 text align center不能在 IE 中工作 本身没有浮动到中心 如果要将块元素置于另一个块元素的中心 请执行以下操作 div div Stuff to center div div with
  • Typescript:如何在 React 中添加历史对象的类型检查?

    我有以下代码 它接收历史对象作为道具 const ChildComponent history gt div div div div
  • PHP echo SQL 计数[重复]

    这个问题在这里已经有答案了 好的 所以我遇到了问题 我似乎无法在 PHP 中成功回显 SQL 计数 SQL SELECT TableA C COUNT FROM TableA JOIN TableB ON TableA C TableB D
  • 32位机器如何处理大于2^32的数字?

    I am trying to understand how calculations involving numbers greater than 232 happen on a 32 bit machine C code cat size