Apple M1 Mac mini入手,看看arm汇编长什么样

最近入手新玩具——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!!!

Mathematica benchmark 2.96分

目前发现在终端下,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来加载地址的。。。

看到区别了吧。。。

后面有空再更。。。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注