关于32位和64位,这个概念一直让人比较懵。
在买电脑的时候,我们看到过32位和64位CPU。
下软件的时候,我们也看到过32位或64位的软件。
就连装虚拟机的时候,我们也看过32位和64位的系统。
在写代码的时候,我们的数值,也可以定义为int32或者int64。
我们当然很清楚,装软件的时候,一般64位的系统就选64位的软件,肯定不出错,但是这又是为什么呢?既然CPU,软件,操作系统,数值大小都有32位和64位,他们之间就可以随意组合成各种问题,比如32位的系统能装64位的软件吗?32位的系统能计算int64的数值吗?他们之间到底有什么关系?这篇文章会尝试解释清楚。
从代码到到可执行文件
我们从熟悉的场景开始说起,比方说,我们写代码的时候,会在代码编辑器里写入。
// test.c
#include <stdio.h>
int main()
{
int i,j;
i = 3;
j = 2;
return i + j;
}
复制代码
但这个代码是给人看的,机器可看不懂,于是这段代码,还会经过被编译器转成汇编码。
汇编码就是我们大学的时候学的头秃的这种
// gcc -S test.c
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset %rbp, -16
movq %rsp, %rbp
.cfi_def_cfa_register %rbp
movl $0, -4(%rbp)
movl $3, -8(%rbp)
movl $2, -12(%rbp)
movl -8(%rbp), %eax
addl -12(%rbp), %eax
popq %rbp
retq
复制代码
大家也别去看上面的内容,没必要。
而汇编,总归还是有各种movl,pushq这些符号,虽然确实不好看,但说到底还是给人看的,而机器cpu要的,说到底还是要0101这样的二进制编码,所以还需要使用汇编器将汇编转成二进制的机器码。我们可以看到下面内容分为3列,左边是指令地址, 右边是汇编码内容,中间的就是指令机器码,是16进制,可以转成二进制01串,这就是机器cpu能认识的内容了。
// objdump -d test
0000000000001125 <main>:
1125: 55 push %rbp
1126: 48 89 e5 mov %rsp,%rbp
1129: c7