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.