32位机器如何处理大于2 ^ 32的数字? [英] How are numbers greater than 2^32 handled by a 32 bit machine?

查看:349
本文介绍了32位机器如何处理大于2 ^ 32的数字?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图了解在32位计算机上如何进行大于2 32 的数字计算。

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

C代码

$ 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输出

$ 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行到底发生了什么?

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

Is this some kind of string concatenation at the assembly level?

推荐答案

__ printf_chk printf 的包装,它检查堆栈是否溢出,并接受一个附加的第一个参数a标志(例如参见这里。)

__printf_chk is a wrapper around printf which checks for stack overflow, and takes an additional first parameter, a flag (e.g. see here.)

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

pow(2, 64) - 1 has been optimised to 0xffffffffffffffff as the arguments are constants.

按照通常的调用约定, __ printf_chk的第一个参数() int标志)是堆栈上的32位值(位于%esp 调用 时)。下一个参数 const char * format 是一个32位指针(堆栈中的下一个32位字,即%esp + 4 )。接下来要打印的64位数字占据了接下来的两个32位字(分别为%esp + 8 %esp + 12 ):

As per the usual calling conventions, the first argument to __printf_chk() (int flag) is a 32-bit value on the stack (at %esp at the time of the call instruction). The next argument, const char * format, is a 32-bit pointer (the next 32-bit word on the stack, i.e. at %esp+4). And the 64-bit quantity that is being printed occupies the next two 32-bit words (at %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

编译器实际上已将其重写为:

The compiler has effectively rewritten this:

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位字,地址从图的底部开始逐渐增加):

...and, at runtime, the stack layout for the call looks like this (showing the stack as 32-bit words, with addresses increasing from the bottom of the diagram upwards):

        :                 :
        :     Stack       :
        :                 :
        +-----------------+
%esp+12 |      0xffffffff | \ 
        +-----------------+  } <-------------------------------------.
%esp+8  |      0xffffffff | /                                        |
        +-----------------+                                          |
%esp+4  |address of string| <---------------.                        |
        +-----------------+                 |                        |
%esp    |               1 | <--.            |                        |
        +-----------------+    |            |                        |
                  __printf_chk(1, "max unsigned long long = %llu\n", |
                                                    0xffffffffffffffffULL);

这篇关于32位机器如何处理大于2 ^ 32的数字?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆