# Assembly x86/Introdução
## Programação com Assembly

A linguagem Assembly (também conhecida por Assembler ou ASM) é a linguagem de programação mais primitiva que existe. Tendo aparecido como uma ajuda aos primeiros programadores que, antes disso, utilizavam exclusivamente código máquina para programar, o Assembly preserva toda a flexibilidade que o hardware oferece, permitindo que o programador otimize o seu código à unha, utilizando truques que seriam impossíveis numa linguagem de programação de alto nível, como o C.
Ao programar em Assembly, o programador utiliza as instruções que o seu processador reconhece, mas não tem de escrevê-las na forma nativa do processador, isto é, não tem a necessidade de escrever os códigos binários que indicam ao processador para executar determinada operação (códigos esses conhecidos por opcodes). Em vez disso, o programador tem ao seu dispor um conjunto de mnemônicas a serem posteriormente traduzidas para linguagem de máquina por um programa chamado assembler, assemblador ou montador. Os assembladores normalmente fornecem também outros recursos que facilitam muito a programação em baixo nível, o mais onipresente dos quais é a possibilidade de definir símbolos, que são normalmente utilizados para referenciar localizações na memória conhecidas pelo assemblador. Outros recursos incluem a possibilidade de fazer operações aritméticas (e, alguns casos, algébricas) no momento da assemblagem e os pré-processadores, que oferecem funcionalidades muitas vezes superiores aos oferecidos pelo pré-processador do C.

## O Assembly nos dias de hoje

A atualidade do panorama da programação é largamente contrária à programação em baixo nível no geral. As mentes bem pensantes geralmente desaconselham a utilização de Assembly, ou até mesmo do C, para novos projetos e incentivam a reescrita de software escrito em Assembly numa linguagem de alto nível.
A verdade é que muita coisa que se diz sobre a necessidade de dar alguma importância à programação, e até mesmo ao estudo, do Assembly nos dias de hoje. Regra geral, qualquer programador dá uma série de razões para não usar Assembly. Sendo discutível a validade de muitas das razões que esses programadores alegam, apenas apresentamos a mais inquestionável. Qualquer documento didático sobre Assembly tipicamente encarrega-se de desmotivar as pessoas antes de começar a ensinar a linguagem em si, mas aqui vamos tentar que as pessoas não fiquem obcecadas com o problema de encontrar uma razão para usar Assembly, e que usem realmente a linguagem e formem uma opinião sobre ela. Admitamos que o leitor deseja usar Assembly porque quer.
O principal problema é que o código escrito em Assembly não é independente da plataforma nem facilmente portável. Sobre isto há três coisas a dizer:
* O código Assembly escrito para determinada arquitetura de processadores nunca irá correr num processador de outra arquitetura sem uma reescrita completa. Não se trata apenas de portar, no sentido clássico da coisa, mas basicamente de repetir todo o processo de desenvolvimento, mas com outras instruções (as de outro processador).
* Diferentes sistemas operativos utilizam diferentes ABIs (Application Binary Interface), o que significa que um programa escrito para um sistema operativo não irá facilmente correr noutro. Apesar de haver algumas saídas para esta dificuldade (das quais o programador iniciado rapidamente se aperceberá), alguns casos estas podem ser bastante complicadas de implementar. A título de exemplo, indicamos o FASM (um assemblador escrito em assembly) que foi portado para DOS, Unix e Windows. O "segredo" deste programa é a adaptação do código da interface com o utilizador, que chama as partes internas do assemblador, que são essencialmente algorítmicas e, portanto, não necessitam de ser portadas.
* Devemos ter, no entanto, atenção ao fato de que é relativamente fácil e prática habitual escrever código C que também não é portável. Certas práticas que saem fora do âmbito da biblioteca padrão geralmente necessitam de adaptação para compilar sem problemas tanto em Unix como Windows.

## Vantagens de utilizar Assembly

Há quatro vantagens gerais em usar Assembly:
* Otimização da rapidez de execução Em Assembly, é sempre possível escrever código mais rápido, embora essa vantagem não venha automaticamente, pois requer treino.
* Otimização do espaço ocupado em memória Os compiladores, por vezes, traduzem o código de uma maneira demasiado mecanizada e geram código supérfluo. Usando Assembly, este problema não existe porque o código é gerado por seres pensantes.
* Capacidades da linguagem As linguagens de alto nível, como o C ou o Python, existem para eliminar ou atenuar o problema da portabilidade. Se estas incluíssem funções e instruções específicas de determinado processador, falhariam nesse objetivo. Com Assembly, isso não acontece, uma vez que as linguagens Assembly são específicas de cada processador e não aspiram à portabilidade. Por esta razão, o kernel de um sistema operativo necessita sempre de incluir algum código Assembly, ainda que a maior parte possa ser escrita em C ou noutra linguagem de alto nível.
* Conhecimento Acontece também que, geralmente, aqueles que sabem Assembly, mesmo que nunca a cheguem a utilizar ativamente a linguagem, acabam por escrever código mais eficiente mesmo quando programam em alto nível. Isso acontece porque fica-se a saber quais as operações que o compilador mais facilmente/efetivamente otimiza.

## Conciliando os dois mundos

A quem quiser programar em Assembly, recomenda-se que dê atenção à questão da portabilidade. Se o programa não tiver, definitivamente, como objetivo ser utilizado por outros que não o programador, o problema fica eliminado. Mas deve-se tomar em atenção que, para certos programas, isto pode não ser óbvio (um bom exemplo é o kernel do Linux).
Se o programador tenciona apenas reescrever algumas partes do programa em Assembly de modo a melhorar a rapidez, é bom que mantenha uma versão portável. Quem use uma arquitetura diferente da do programador iria de outra forma ter problemas ao tentar compilar o programa.