Programando junto com C

Aprendendo a mesclar Assembly e C

Se voc√™ leu o conte√ļdo do livro at√© aqui j√° tem uma boa base para entender como o Assembly x86 funciona e como us√°-lo. Tamb√©m j√° tem uma boa no√ß√£o do que est√° fazendo, entende bem o que o assembler faz e o que ele est√° produzindo como sa√≠da, sabe como efetuar c√°lculos em paralelo usando SSE inclusive com valores de ponto flutuante.

Em outras palavras voc√™ j√° tem a base necess√°ria para realmente entender como as coisas funcionam, n√£o decoramos instru√ß√Ķes aqui mas sim entendemos as coisas em seu √Ęmago. Agora est√° na hora de dar um passo a frente e entender como usar Assembly de uma maneira √ļtil no "mundo real", vamos aprender a usar C e Assembly juntos afim de escrever programas.

J√° estamos fazendo isso desde o come√ßo mas n√£o entramos em muitos detalhes pois eu queria que inicialmente o foco fosse em entender como as coisas funcionam, essa √© a parte legal ūüėĀ.

Ferramentas

Como já mencionado antes vamos usar o GCC para compilar nossos códigos em C. Mas diferente dos capítulos anteriores que usamos o NASM, neste aqui vamos usar o assembler GAS com sintaxe da AT&T porque assim aprendemos a ler código nessa sintaxe e a usar o GAS ao mesmo tempo.

Por convenção a gente usa a extensão .s (ao invés de .asm) para código ASM com sintaxe da AT&T, então é a extensão que irei usar daqui em diante para nomear os arquivos.

Assim como fizemos em A base aqui está um código de teste para garantir que o seu ambiente está correto:

#include <stdio.h>

int assembly(void);

int main(void)
{
  printf("Resultado: %d\n", assembly());
  return 0;
}

O nome do executável do GAS é as e quando você instala o GCC ele vem junto, então você já tem ele instalado aí. Já pode tentar compilar com:

$ as assembly.s -o assembly.o
$ gcc main.c -c -o main.o
$ gcc *.o -o test

Caso tenha algum problema e precise de ajuda, pode entrar no fórum do Mente Binária e fazer uma pergunta.

Vendo o código de saída do GCC

Ao usar o GCC √© poss√≠vel passar o par√Ęmetro -masm=intel para que o compilador gere c√≥digo Assembly na sintaxe da Intel, onde por padr√£o ele gera c√≥digo na sintaxe da AT&T. Voc√™ pode ver o c√≥digo de sa√≠da da seguinte forma:

$ gcc main.c -o main.s -S -masm=intel -fno-asynchronous-unwind-tables

Onde a flag -S faz com que o compilador apenas compile o c√≥digo, sem produzir o arquivo objeto de sa√≠da e ao inv√©s disso salvando o c√≥digo em Assembly. Pode ser √ļtil fazer isso para aprender mais sobre a sintaxe do GAS.

A flag -fno-asynchronous-unwind-tables serve para desabilitar as diretivas CFI e melhorar a leitura do c√≥digo de sa√≠da. Essas diretivas servem para gerar informa√ß√£o √ļtil para um depurador mas para fins de leitura do c√≥digo n√£o precisamos delas.

Voc√™ tamb√©m pode habilitar as otimiza√ß√Ķes do GCC com a op√ß√£o -O2 assim o c√≥digo de sa√≠da ser√° otimizado. Pode ser interessante fazer isso para aprender alguns truques de otimiza√ß√£o.

Last updated