最近入手新玩具——Apple M1 Mac mini,作为搞计算机的,用过各型架构(x86、power) 超算的,arm其实并不算难用。。。x86用久了,换个arm玩玩还挺新鲜的。。。话说十年前,我跟人讨论arm会不会是个人计算机的未来,果然十年后出现了苗头,并入手一个能干活的个人计算机(我在五六年前买的树莓派这种不能算严格意义的个人计算机,计算能力太弱)
用了两天,发现兼容性不错,不过最近苹果服务器抽风了,已购的ios app无法下载,新购的正常。配置如下,16G的内存,512的闪存,基本足够。
目前大部分软件正常,除了那些破解起来极其复杂的软件,基本都能用,Matlab,Mathematica基本不在话下,Latex常备的MacTex,TexMaker,Jabref都能正常运行。Mac App Store里的Intel版本的微信、扣扣正常使用。。。Mathematica 2.96分,接近我一台I7 8700的水平,而且还是代码转译过的结果,就一句,苹果Niubility!!!
目前发现在终端下,x86编译的应用正常,我这人有干净系统强迫症,不喜欢Homebrew这种toolkit,基本上常用的应用我都是下载源代码编译,存在云端,例如7z,adb,smartctl等等。。。
最惊喜的是这些x86编译的应用居然在arm上正常运行,完全无感,没有任何报错。smartctl这种对硬件端口依赖的应用,居然在arm上能正常跑。
于是乎写了个小程序,看看ARM和x86的汇编有啥区别,网上的各位都是跑视频转码这些,技术含量有点那啥,今天我们来看看干货,到底x86和m1编译的程序有什么不同。。。
#include<iostream>
using namespace std;
int main()
{
int k=2;
k++;
cout<<"Hello:"<<k<<endl;
}
程序很简单,小学生都懂,
我还有一个13 Late的rmbp,如今还在正常使用,所以可以正常编译x86的,来看汇编区别
_main: ; @main
.cfi_startproc
; %bb.0:
sub sp, sp, #32 ; =32
stp x29, x30, [sp, #16] ; 16-byte Folded Spill
add x29, sp, #16 ; =16
.cfi_def_cfa w29, 16
.cfi_offset w30, -8
.cfi_offset w29, -16
mov w8, #2
stur w8, [x29, #-4]
ldur w8, [x29, #-4]
add w8, w8, #1 ; =1
stur w8, [x29, #-4]
adrp x0, __ZNSt3__14coutE@GOTPAGE
ldr x0, [x0, __ZNSt3__14coutE@GOTPAGEOFF]
adrp x1, l_.str@PAGE
add x1, x1, l_.str@PAGEOFF
bl
以上是M1上编译的结果,因为涉及到很多库的原因,其他代码会很长,但是核心的代码,我们看到
mov w8, #2 (int k=2;)
add w8, w8, #1 (k++;)
adrp x1, l_.str@PAGE (cout<<"Hello:"<<k<<endl;)
mov,add在x86上很常见,但是在传字符串地址的时候,这里用的是adrp,armv8上的指令
_main: ## @main
.cfi_startproc
## %bb.0:
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset %rbp, -16
movq %rsp, %rbp
.cfi_def_cfa_register %rbp
subq $16, %rsp
movq __ZNSt3__14coutE@GOTPCREL(%rip), %rdi
movl $2, -4(%rbp)
movl -4(%rbp), %eax
addl $1, %eax
movl %eax, -4(%rbp)
leaq L_.str(%rip), %rsi
callq
以上是x86上的汇编结果,三行代码对应如下
movl $2, -4(%rbp) (int k=2;)
addl $1, %eax (k++;)
leaq L_.str(%rip), %rsi (cout<<"Hello:"<<k<<endl;)
这里x86是用leaq来加载地址的。。。
看到区别了吧。。。
后面有空再更。。。