Linguagem assembly: diferenças entre revisões

Conteúdo apagado Conteúdo adicionado
m Desfeita(s) uma ou mais edições de LF337 (Remoção de conteúdo válido e referenciado), com Reversão e avisos.
Correção e melhoramento do conteúdo.
Linha 1:
{{mais notas|data=janeiro de 2014}}
{{Ver desambig}}
'''''Assembly''''' ou '''linguagem de montagem''' é uma notação legível por humanos para o [[código de máquina]] que uma [[arquitetura de computador]] específica usa, utilizada para programar dispositivos computacionais, como [[microprocessador]]es e [[microcontrolador]]es. A linguagem de máquina, que é um mero padrão de [[bit]]s, torna-se legível pela substituição dos valores em bruto por símbolos chamados [[mnemónico]]s<ref>[http://knol.google.com/k/assembly# Assembly - Knol]</ref><ref>[http://www.ic.uff.br/~loques/orgcomp/cap7-assembler.pdf Linguagem de montagem - UFF]</ref>.
 
'''''Assembly'''''(sigla '''ASM''') ou '''linguagem de montagem''' é uma [[linguagem de baixo nível]] que utiliza de [[mnemónico]]s como instruções<ref>[http://knol.google.com/k/assembly# Assembly - Knol]</ref>.
Por exemplo, enquanto um computador sabe o que a [[instrução-máquina]] IA-21 (<code>10110000 01100001</code>) faz, para os programadores é mais fácil recordar a representação equivalente em instruções mnemónicas <code>MOV AL, 61h</code>. Tal instrução ordena que o valor [[Sistema hexadecimal|hexadecimal]] 61 (97, em [[Sistema decimal|decimal]]) seja movido para o [[registrador (informática)|registrador]] 'AL'.
 
A conversão da linguagem de montagem para o código de máquina é feita pelo montador ou ''assembler'', que é basicamente um tradutor de comandos, sendo mais simples que um [[compilador]].
 
== Arquitetura ==
Cada instrução Assembly é montada em [[opcodes]] gerando um [[código de máquina]].
Ao contrário do que acontece nas [[Linguagem de programação de alto nível|linguagens de alto nível]], existe (até certo ponto) uma correspondência de 1 para 1 entre a linguagem de montagem simples e a linguagem de máquina. Por isso a tradução do código de montagem em código de máquina não é chamada [[compilador|compilação]], mas montagem. Consegue-se transformar a linguagem de montagem em linguagem de máquina recorrendo a um montador (também chamado ''assembler'', originado do termo assemblé em [[Língua francesa|francês]]){{carece de fontes}}, e a transformação inversa faz-se recorrendo a um [[desmontador]] (também chamado ''disassembler'').
O processo de montagem é feito por um montador(ou ''Assembler''), que é o programa de computador responsável por montar o código Assembly em código de máquina.
 
Um exemplo de código montado para a arquitetura x8086.<br>
Cada [[arquitetura de computador]] tem a sua própria linguagem de máquina e, portanto, a sua própria linguagem de montagem. Essas linguagens de montagem diferem no número e tipo de operações que suportam. Também têm diferentes tamanhos e números de registradores, e diferentes representações dos tipos de dados armazenados. Enquanto todos os computadores de utilização genérica são capazes de desempenhar essencialmente as mesmas funções, o modo como o fazem é diferente.
Assembly: <code>mov ah, 0Eh</code><br>
Código de máquina: <code>B4 0E</code>
 
Onde o opcode B4 é o responsável por atribuir um valor ao [[registrador (informática)|registrador]] AH.
Além disso, podem existir conjuntos múltiplos de mnemónicas, ou sintaxes de linguagem de montagem, para um único conjunto de instruções. Nestes casos, o conjunto mais popular é aquele que é utilizado pelo fabricante na sua documentação.
Apesar de muitos pensarem em código de máquina como uma sequência de valores [[binário]]s, ele é comumente representado em valores [[hexadecimal|hexadecimais]].
 
Cada arquitetura de computador tem seu próprio código de máquina. Logo necessitará de um montador específico para sua [[arquitetura de computadores|arquitetura de computador]].
No mercado de [[Computador pessoal|PCs]], dominado por processadores Intel e AMD, atualmente existem duas arquiteturas. Primeiro a [[IA32]] (genericamente chamada de [[i386]], [[x86]] ou [[x86-32]]), criada pela [[Intel]] em 1985 e primeiramente utilizada pelo [[processador]]es [[i386]] e segundo a [[IA32-EM64T]] (ou [[IA32-AMD64]] ) criada em 2002 pela [[AMD]] (Mas também utilizada pela [[Intel]] hoje). O [[IA32]] utiliza o grupo de instruções chamado [[x86]], e o [[IA32-EM64T]] utiliza o grupo chamado [[x86-64]]. As duas arquiteturas usam números diferentes de registradores gerais e tamanho. Enquanto os registradores do x86 são [[32 bit]]s os da x86-64 são [[64 bit]]s.{{carece de fontes}}
Apesar do resultado final ser o mesmo, existem diferenças entre os opcodes de cada arquitetura<ref>[http://www.ic.uff.br/~loques/orgcomp/cap7-assembler.pdf Linguagem de montagem - UFF]</ref>.
 
== Registradores ==
Os registradores de uso geral da arquitetura x86 são:
Os registradores são pequenas e rápidas áreas de memória utilizada para diversos fins.
* ''%EAX'' - registrador acumulador
Alguns desses registradores são utilizados para designar o locais da memória em que o processador vai executar ou pegar informações.
* ''%EBX'' - registrador base
* ''%ECX'' - registrador contador
* ''%EDX'' - registrador de dados
* ''%ESI'' - registrador de índice da fonte dos dados
* ''%EDI'' - registrador de índice do destino dos dados
* ''%EBP'' - registrador [[Ponteiro (programação)|ponteiro]] para a moldura de chamada de função
* ''%ESP'' - registrador ponteiro para a pilha de execução
 
=== Registradores de segmento ===
Os registradores de uso geral da arquitetura x86-64 são:
Segmento é uma área da memória usada para armazenar instruções, dados ou usado pela [[pilha (informática)|pilha]]<ref>[http://www.fhenriques.uac.pt/AC/documentos/Memoria.pdf [PDF] Memória Segmentos.</ref>.
* ''%RAX'' - registrador valor de retorno
Os seguintes registradores são usados para designar estas área:
* ''%RBX'' - registrador base
* CS - Code Segment, segmento de código em execução.
* ''%RCX'' - registrador contador
* ''%RDX''DS - registradorData Segment, segmento de dados.
* SS - Stack Segment, segmento de pilha.
* ''%RSI'' - registrador de índice da fonte dos dados
* ES - Extra Segment, segmento extra para armazenamento de dados.
* ''%RDI'' - registrador de índice do destino dos dados
* ''%RBP'' - registrador ponteiro para a moldura de chamada de função
* ''%RSP'' - registrador ponteiro para a pilha de execução
* ''%R8 '' - registrador de dados
* ''%R9 '' - registrador de dados
* ''%R10'' - registrador ponteiro para a moldura de chamada de função
* ''%R11'' - registrador de linking
* ''%R12'' - registrador de base
* ''%R13'' - registrador de base
* ''%R14'' - registrador de base
* ''%R15'' - registrador de base
 
=== Registradores ponteiros ===
Esses nomes derivam da forma como eram utilizados nas arquiteturas anteriores a IA32 ([[8086]], [[80286]]…), em que cada registrador desempenhava um papel específico. Na arquitetura i386, todos eles são de uso geral, embora eles continuem a poder ser utilizados em seus papéis tradicionais.
Esses registradores são utilizados para indicar posições da memória de instruções e dados.
 
* BP - Base Pointer, indica o início da pilha.
A arquitetura IA32 ainda apresenta os registradores de segmento CS, DS, ES, SS, FS e GS, um [[contador de programa]] EIP, um registro de sinalizadores EFLAGS, 8 registradores de [[vírgula flutuante]] e seus sinalizadores associados. Existem também registradores utilizados pelo [[sistema operacional]] para controle da execução em [[modo protegido]], bem como outros registradores de uso específico ([[depuração]], controle de desempenho, etc.).
* IP - Instruction Pointer, instrução atualmente executada.
* SP - Stack Pointer, posição atual da pilha.
* SI - Source Index, usado em operações com strings para apontar o índice da string fonte.
* DI - Destination Index, aponta o índice da string destino.
 
=== Registradores de dados ===
;Instruções aritméticas:
Usado de forma geral no programa, para várias operações. Embora possam ser utilizados em outras ocasiões, cada um desses registradores foram feitos para tarefas específicas.
* Adição: ADD, ADC, INC, XADD, AAA e DAA;
* Subtracção: SUB, SBB, DEC, AAS e DAS;
* Multiplicação: MUL, IMUL e AAM;
* Divisão: DIV, IDIV e AAD.
 
* AX - Registrador Acumulador, usado para operações aritméticas.
== Montador ==
* BX - Registrador de Base, usado para indexar endereços na memória.
O '''montador''' ou '''assembler''' (não confundir com assembly) é um programa que cria o [[código objeto]] traduzindo as instruções da linguagem de montagem (assembly) para código de máquina. Além dos comandos básicos, que são traduzidos diretamente para a linguagem de máquina, alguns montadores também aceitam diretivas, que são comandos específicos para o montador. Por exemplo, é possível definir constantes na memória utilizando diretivas.<ref name="intro-ranido">{{citar web |url=http://www.ic.unicamp.br/~ranido/mc404/faiska/cap2.pdf |título=Introdução à Organização de Computadores e Linguagens de Montagem |acessodata=11 de março de 2012 |autor=Ricardo Anido|data=25 de Fevereiro de 2011|formato=PDF |publicado=Universidade Estadual de Campinas }}</ref>
* CX - Registrador Contador, usado para contagem usando a instrução de loop.
* DX - Registrador de Dados, usado para armazenar dados de forma geral. Seja para cálculos ou operações de [I/O].
 
Esses registradores na verdade são uma junção de dois registradores de 8bits, somando ao todo 16bits.
O montador possui tabelas, onde armazena informações importantes sobre o programa que está sendo montado. Tabelas de rótulos, de constantes e de comandos são as mais comuns.<ref name="intro-ranido" />
Eles são <code>AH, AL, BH, BL, CH, CL, DH, DL</code>.
 
Também existem versões de 32 e 64bits desses registradores. Onde eles são:
== Exemplos de código de montagem ==
* 32 bits - '''EAX, EBX, ECX, EDX'''
=== Arquitetura [[Intel]] ===
* 64 bits - '''RAX, RBX, RCX, RDX'''
Código em assembly que usa a sintaxe intel.
<syntaxhighlight lang="asm">
Decimal Endereço OPcode Operandos
 
== Exemplos de código Assembly ==
2089872304 7C90EBB0 sub esp, 2D0h
Um exemplo de código [[Programa Olá Mundo|Olá Mundo]] feito para arquitetura x8086:
2089872310 7C90EBB6 mov dword ptr [ebp+FFFFFDDCh], eax
2089872316 7C90EBBC mov dword ptr [ebp+FFFFFDD8h], ecx
2089872322 7C90EBC2 mov eax, dword ptr [ebp+8]
2089872325 7C90EBC5 mov ecx, dword ptr [ebp+4]
2089872328 7C90EBC8 mov dword ptr [eax+0Ch], ecx
2089872331 7C90EBCB lea eax, [ebp+FFFFFD2Ch]
2089872337 7C90EBD1 mov dword ptr [eax+000000B8h], ecx
2089872343 7C90EBD7 mov dword ptr [eax+000000A4h], ebx
2089872349 7C90EBDD mov dword ptr [eax+000000A8h], edx
2089872355 7C90EBE3 mov dword ptr [eax+000000A0h], esi
2089872361 7C90EBE9 mov dword ptr [eax+0000009Ch], edi
2089872367 7C90EBEF lea ecx, [ebp+0Ch]
2089872370 7C90EBF2 mov dword ptr [eax+000000C4h], ecx
2089872376 7C90EBF8 mov ecx, dword ptr [ebp]
2089872379 7C90EBFB mov dword ptr [eax+000000B4h], ecx
2089872385 7C90EC01 mov ecx, dword ptr [ebp-4]
2089872388 7C90EC04 mov dword ptr [eax+000000C0h], ecx
2089872394 7C90EC0A mov word ptr [eax+000000BCh], cs
2089872400 7C90EC10 mov word ptr [eax+00000098h], ds
2089872406 7C90EC16 mov word ptr [eax+00000094h], es
2089872412 7C90EC1C mov word ptr [eax+00000090h], fs
2089872418 7C90EC22 mov word ptr [eax+0000008Ch], gs
2089872424 7C90EC28 mov word ptr [eax+000000C8h], ss
2089872430 7C90EC2E mov dword ptr [eax], 10007h
2089872436 7C90EC34 push 1
2089872438 7C90EC36 push eax
2089872439 7C90EC37 push dword ptr [ebp+8]
2089872442 7C90EC3A call 7C90E252
2089872447 7C90EC3F sub esp, 20h
2089872450 7C90EC42 mov dword ptr [esp], eax
2089872453 7C90EC45 mov dword ptr [esp+4], 1
2089872461 7C90EC4D mov dword ptr [esp+10h], 0
2089872469 7C90EC55 mov eax, dword ptr [ebp+8]
2089872472 7C90EC58 mov dword ptr [esp+8], eax
2089872476 7C90EC5C mov eax, esp
2089872478 7C90EC5E push eax
2089872479 7C90EC5F call 7C90EBAC
</syntaxhighlight>
 
<syntaxhighlight LANG="asm">
=== Microprocessador Texas Instruments TMS320C2x ===
lea si, string
<syntaxhighlight lang="asm">
call printf
LOOP:
LARP AR1
LRLK AR1, apontador
ADRK TAMANHO_CONSTANTE
ADRK fimcon_rx
LAC *
BZ NAOPASSARAM10MS
ZAC
SACL *
LARP AR1
LRLK AR1,apontador+CONSTANTE_A
ADRK controle
LAC *
BZ LOOP ;Não decorrido tempo: fica no loop
 
hlt
NAOPASSARAM10MS:
string db "Ola mundo!", 0
SACL *
LARP AR1
B LOOP
</syntaxhighlight>
 
printf PROC
=== Microprocessador Texas Instruments TMS320C5x ===
mov AL, [SI]
<syntaxhighlight lang="asm">
cmp AL, 0
LOOP:
je pfend
mvmm ar1, ar3 ;move conteúdo de ar1 para ar3
rpt #10 ;repete
mvdd *ar3+, *ar5+ ;move word endereçada por ar1 para pos. end. por ar6
 
mov AH, 0Eh
;Instruçoes com acumulador:
int 10h
STM #1000h, AR1 ;carrega ar1 com a constante 1000h
inc SI
LD #0, A ;zera o acumulador
jmp printf
STL A, *AR1 ;armazena no acumulador mínimo
LD #1, A ;carrega o acumulador com a constante mínima "1"
STL A, *AR1 ;armazena o acumulador mínimo no endereço de ar1
LD #65535, A ;carrega acumulador com a constante "65535"
STL A, 10 ;armazena o acumulador mínimo no endereço 10
STH A, 10 ;armazena o acumulador máximo no endereço 10
STL A, *AR1 ;armazena o acumulador mínimo no endereço de ar1
STH A, *AR1 ;armazena o acumulador máximo no endereço de ar1
 
pfend:
;Instruções com registradores auxiliares:
ret
STM #1, AR1 ;carrega ar1 com a constante "1"
printf ENDP
STM #2, AR0 ;carrega ar0 com a constante "2"
</syntaxhighlight>
MAR *AR1+0 ;adiciona o conteúdo de ar0 to ar appointed by arp (1)
MVDK 256, *(AR2) ;carrega ar2 with content of address 256
MAR *AR1+ ;incrementa ar apontado por arp (1)
MVKD *(AR2), 256 ;aloja conteúdo de ar2 no endereço 256
MAR *AR1- ;decrementa ar appointed by arp (1)
 
;Instruções de teste de bit:
BITF *AR1, #128 ;TESTA BIT D7
BC ptr, NTC ;vai para ptr se bit for igual a 0
MAR *AR1+ ;incrementa ar apontado por arp (1)
 
ptr:
MAR *+AR4(-128) ;sbrk 80h
 
;Instruções de uso de ponteiros:
mvdm *(VETORAL), ar1 ;move conteúdo da memória apontada para o ar (transforma arn em ponteiro)
mvmd ar1, *(VETORAL) ;mvmd restaura ponteiro(VETORAL) de acordo com arn
b LOOP
</syntaxhighlight>
 
== Ver também ==
Linha 189 ⟶ 98:
 
[[Categoria:Linguagens de programação]]
[[Categoria:Montadores]]
[[Categoria:Software em linguagem de montagem]]