[Assembly no macOS M1/ARM64.]

A história é a seguinte, eu tinha encontrado uma ótima oferta de dois computadores  do início dos anos 90 ainda usando processadores Zilog Z80, não estavam perfeitos, mas o valor estava ok. 

Daí, um grande amigo, com muito mais bom senso, aconselhou que eu parasse de gastar energia e dinheiro com máquina velha e sugeriu que para aplacar essa febre de nerdisse eu estudasse assembly do ARM, que pelo menos pode ser útil. 

E quer saber? Ele tem razão. Então aqui estou eu, iniciando a brincadeira com asm para ARM.

Não é Olá Mundo

No lugar do tradicional “olá mundo” preferi algo ainda mais simples ainda, e potencialmente, mais útil. Em muitos sistemas operacionais existem dois comandos extremamente simples e uteis, o true e o false.

Hoje em dia nos sistemas modernos esses dois comandos fazem parte do shell, eles não são mais arquivos separados, mas o funcionamento continua o mesmo, o true retorna zero e o false retorna 1 e esse valor de retorno pode ser recuperado pela variável “$?”

Obviamente o código-fonte do true e false são idênticos, só buda um bit.

True

.global _start
.align 4

_start:
	mov     X0,  #0
	mov     X16, #1
	svc     #0x80

False

.global _start
.align 4

_start:
	mov     X0,  #1
	mov     X16, #1
	svc     #0x80

Como pode ver os dois códigos são quase idênticos, e o que eles fazem é colocar o valor de retorno no registrador X0 e no registrador X16 a função que deve ser chamada, no caso a função 1 é exit. E por fim, chamamos o syscall 0x80 que vai executar a função.

Makefile

APPLICATIONS = true false
SYSLIBROOT = `xcrun -sdk macosx --show-sdk-path`

all: $(APPLICATIONS)

clean:
	rm *.o
	rm $(APPLICATIONS)

true.o: true.s
	as -o true.o true.s

true: true.o
	ld -o true true.o -lSystem -syslibroot $(SYSLIBROOT) -e _start

false.o: false.s
	as -o false.o false.s

false: false.o
	ld -o false false.o -lSystem -syslibroot $(SYSLIBROOT) -e _start

A maior diferença entre as outras plataformas, é no Makefile que precisa compilar corretamente para M1 e macOS, por exemplo, o macOS requer o executável tenha um link com a biblioteca System. É possível fazer um executável completamente monolítico, mas daria bem mais trabalho.

Código-fonte

Aqui vai o código-fonte dos exemplos.

Vídeos com explicação

Conclusão

Ainda estou muito no princípio dessa brincadeira, mas o ARM é bem interessante, eu pensei que estranharia muito mais por a sintaxe ser bem diferente do Intel que estou acostumado. Mas o ARM pareceu bem ok, não apenas o M1 no macOS, mas também nos modelos mais modernos de Raspberry Pi que usam ARM64.

Assembly é interessante, mas hoje em dia é bem menos necessário do que já foi, quando eu comecei a programar era basicamente mandatório ter pelo menos algum conhecimento de assembly até para coisas simples, mas era outra época, código assembly vinha até mesmo em artigos de revistas.

Então vou, sim, brincar um pouco com esses processadores, mas o foco é só se familiarizar com a plataforma.

Cesar Gimenes