𝖂𝖎ƙ𝖎𝖊

Código de máquina: mudanças entre as edições

imported>Ixocactus
m (limpando erros de lint)
 
(46 revisões intermediárias por 28 usuários não estão sendo mostradas)
Linha 1: Linha 1:
Todo [[computador]] não possui um conjunto de instruções que seu processador é capaz de executar. Essas instruções, chamadas de '''código de máquina''', são representadas por sequências de megabytes, normalmente limitadas pelo número de bits do registrador principal da [[CPU]]. Esse código é chamado de código binário. São formados por 0 e 1.<ref>[http://www.portalsaofrancisco.com.br/alfa/historia-do-computador/codigo-de-maquina.php Código de máquina definição - Colégio São Francisco]</ref>
{{Execução de Programa}}


As instruções correspondem a sequências muito simples de operações, como transferir um dado em memória para a CPU ou somar dois valores e são normalmente interpretadas por [[microcódigo]].
[[Ficheiro:hexedit-linux.png|thumb|[[Bootloader]] em código de máquina que exibe o texto "Hello World!" na cor verde.]]


Um programa em '''código de máquina''' consiste de uma sequência de números que significam uma sequência de instruções a serem executadas.
Um programa em '''código de máquina''' consiste de uma sequência de [[bytes]] que correspondem a instruções a serem executadas pelo processador.
É normal a representação da linguagem de máquina por meio de números ([[opcodes]]) constantes e variáveis em [[Sistema binário (matemática)|sistema binário]] ou [[sistema hexadecimal]]. Alguns computadores também têm seu opcodes representados no [[sistema octal]].
As instruções do processador, chamadas de [[opcodes]], são representadas por valores em [[hexadecimal]].<ref>{{link|2=http://www.linfo.org/machine_code.html|3=Machine Code Definition}}</ref>


Microprocessadores têm, normalmente, seus códigos de operação como múltiplos de 2, 8 e 16, pois usam arquiteturas com [[registradores]] de [[8 bit|8]], [[16 bit|16]], [[32 bit|32]], [[64 bit|64]] ou [[128 bit]]s em [[2006]]. Porém, existem máquinas com registradores de tamanho diferente.
== Programação em código de máquina ==
Para se programar em código de máquina, deve-se obter os códigos de instruções do processador utilizado contendo opcodes, operandos e formatos de cada instrução.


Os [[programas de computador]] raramente são criados em linguagem de máquina, mas devem ser traduzidos (por [[compiladores]]) para serem executados diretamente pelo computador. Existe a opção, em voga atualmente, de não executá-los diretamente, mas sim por meio de um [[interpretador]], esse sim rodando diretamente em código de máquina e previamente compilado.
Por esse motivo foi criada uma linguagem de programação chamada [[Assembly]], composta de códigos mnemônicos que expressam as mesmas instruções do processador, embora escritos em [[acrônimo]]s da língua inglesa, tais como ''mov'' ou ''rep'', em vez de [[opcode]]s.


== Visualização de programas em linguagem de máquina ==
== Formato da instrução ==
Estes números não podem ser vistos num editor de texto, ou, caso se tente ver parecem apenas um texto sem significado devido à existência de [[carácter de controle|caracteres de controle]]. Abaixo pode-se ver o que é mostrado ao se abrir um código de máquina de um PC com um editor de texto:
[[Ficheiro:Figura 2.1 Manual da Intel Para Desenvolvedores Volume 2A.png|thumb|Figura 2.1 do Intel® 64 and IA-32 Architectures Developer's Manual: Vol. 2A]]
 
Uma instrução em código de máquina consiste em uma sequência de bytes, onde cada byte significa algo para o processador.
Instruções da arquitetura [[IA-32]] são consistidas por<ref name="vol2A-pagina35">{{citar livro |url=https://www.intel.com.br/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-vol-2a-manual.pdf |lingua=en |pagina=35 |titulo=Intel® 64 and IA-32 Architectures Developer's Manual: Vol. 2A}}</ref>:
* Prefixos opcionais. Onde pode-se usar nenhum prefixo ou um de cada um dos quatro grupos existentes.
* Bytes primários do opcode. Onde o opcode pode ter um, dois ou três bytes de tamanho.
* Se requerido, também pode ter o byte ModR/M. Esse byte consiste em três campos de informações:
** O campo ''mod'' que combinado com o campo R/M pode formar 32 valores diferentes: Oito registradores e 24 modos de endereçamento.
** O campo ''reg/opcode'' especifica o número do registrador ou mais três bits de informação do opcode. O propósito desse campo é especificado no opcode primário.
** O campo ''R/M'', que pode ser usado para um registrador como operando ou pode ser combinado com o campo ''mod'' para especificar um modo de endereçamento.
* Se requerido, pode ter também o byte SIB que serve para especificar três informações sobre endereçamentos de memória. Onde essas informações ficam nos seguintes campos:
** O campo ''scale'' serve para especificar uma escala de endereçamento.
** O campo ''index'' especifica o número do registrador utilizado como índice de acesso ao endereço.
** E o campo ''base'' especifica o número do registrador utilizado como endereço base.


<pre>
Essas informações escritas em Assembly seguindo a sintaxe da Intel, ficam no seguinte formato:
MZÀ�$Pÿv�èŠÿ]Ë3ÀP¸�F�
<syntaxhighlight lang="asm">
ë�ƒF��¸�< uè2Àëä�Àt�Bª
mov dword [ebp + ebx*4], eax
Àu�C†à2Àùã�¬I,"t��"<\u�€<"u�¬I�öАé�îY�Ê.Ž�t�‰�”�C�Û�Û‹ô‹ì+ërâ‹å‰.–�Œ�˜�ã�‰v¸�vüÿv�
</syntaxhighlight>
ÿv��èÅ�ƒÄ�ÿvþÿvü�èüêYY‹V�‹F�ë�Rÿvþÿvü�èWíƒÄ�‹å]ËU‹ìƒìHVW‹~�‹F�‰Fþ�Àu
Onde ebx é o registrador ''index'', ebp é o registrador ''base'' e 4 a escala. Onde escala pode ser os valores 1, 2, 4 ou 8.
´�Í!´3Àé•Š�˜‹ØŠ‡Ïn
</pre>


Pode-se editar o código de máquina usando [[Editor hexadecimal|editores hexadecimais]], como por exemplo o "debug" que roda sobre o [[MS-DOS|DOS]] do [[Windows]]. Com estes programas pode-se ver o código não em binário, mas em hexadecimal, como mostrado abaixo nesta captura da tela do DOS com o debug aberto editando o programa "v.exe": (tecla-se ? para comandos e d para dump)
* Algumas formas de endereçamento precisam de um deslocamento imediato que fica logo após o byte ModR/M, ou o byte SIB se estiver presente. Caso um deslocamento imediato seja necessário, este pode ter um tamanho de um, dois ou quatro bytes.
* Se uma instrução especifica um operando imediato, o operando fica após todos os bytes de deslocamento. E pode ter o tamanho de um, dois ou quatro bytes.


<pre>
== Prefixos ==
C:\Utility>debug v.exe
Os prefixos são bytes inseridos logo antes de um opcode, que serve para alterar a forma com que uma instrução é executada.
-d 0 100
Os prefixos são opcionais e indiferente da ordem, isto é, não faz diferença em que ordem eles são colocados.
0E3D:0000  CD 20 FF 9F 00 9A F0 FE-1D F0 4F 03 F0 07 8A 03  . ........O.....
Além disso, só pode ser utilizado em uma instrução apenas um prefixo de cada grupo. Não sendo possível incluir dois ou mais prefixos pertencentes do mesmo grupo.<ref name="vol2A-pagina35" />
0E3D:0010  F0 07 17 03 F0 07 DF 07-01 01 01 00 02 FF FF FF  ................
0E3D:0020  FF FF FF FF FF FF FF FF-FF FF FF FF BD 0D 4C 01  ..............L.
0E3D:0030  D0 0C 14 00 18 00 3D 0E-FF FF FF FF 00 00 00 00  ......=.........
0E3D:0040  05 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
0E3D:0050  CD 21 CB 00 00 00 00 00-00 00 00 00 00 20 20 20  .!...........
0E3D:0060  20 20 20 20 20 20 20 20-00 00 00 00 00 20 20 20          .....
0E3D:0070  20 20 20 20 20 20 20 20-00 00 00 00 00 00 00 00          ........
0E3D:0080  00 0D 76 2E 65 78 65 0D-44 4F 57 53 5C 73 79 73  ..v.exe.DOWS\sys
0E3D:0090  74 65 6D 33 32 5C 64 6F-73 78 0D 0D 64 61 20 72  tem32\dosx..da r
0E3D:00A0  65 64 65 20 28 63 61 72-72 65 67 61 72 20 61 6E  ede (carregar an
0E3D:00B0  74 65 73 20 64 6F 20 64-6F 73 78 2E 65 78 65 29  tes do dosx.exe)
</pre>


No exemplo acima é mostrado à esquerda o endereço da memória (segmento:offset), ao centro o código à direita como seria o texto em [[ASCII]]. Mais eficiente do que tudo isso seria conseguir um programa dedicado para manipulação de código de máquina.
* Grupo 1
** Prefixos de bloqueio e repetição
*** '''F0h''' - Prefixo LOCK, utilizado para garantir o uso exclusivo da memória compartilhada.<ref>{{link|2=https://docs.oracle.com/cd/E19455-01/806-3773/instructionset-128/index.html|3=LOCK Prefix - Oracle}}</ref>
*** '''F2h''' - Prefixo REPNE/REPNZ.
*** '''F3h''' - Prefixo REP ou REPE/REPZ.
* Grupo 2
** Prefixos de sobreposição de segmentos
*** '''2Eh''' - Segmento CS.
*** '''36h''' - Segmento SS.
*** '''3Eh''' - Segmento DS.
*** '''26h''' - Segmento ES.
*** '''64h''' - Segmento FS.
*** '''65h''' - Segmento GS.
** Prefixos ''Branch Hints'' - Usados em instruções de pulo condicional para se aproveitar da tecnologia [[Branch prediction]].
*** '''2Eh''' - Caminho pouco provável. (usado somente em instruções de pulo condicional)
*** '''3Eh''' - Caminho provável. (usado somente em instruções de pulo condicional)
* Grupo 3
** '''66h''' - Prefixo para sobreposição do tamanho do operando.
* Grupo 4
** '''67h''' - Prefixo para sobreposição do tamanho do endereço.


== Programação em código de máquina ==
== Visualização de programas em linguagem de máquina ==
Para se programar em código de máquina, deve-se obter os códigos de instruções do processador utilizado, contendo opcodes, operandos e formatos de cada instrução.
Um programa em código de máquina é um [[arquivo binário]]. Como tal, não pode ser visualizado em um editor de texto.


Por esse motivo, foi criada uma linguagem de programação chamada [[linguagem de montagem]] (Assembly Language), composta de códigos mnemônicos que, do ponto de vista técnico, é tão próxima do processador quanto o código de máquina, mas é humanamente mais fácil de se compreender uma vez que seus códigos são geralmente acrônimos do inglês. Por exemplo ´mov´ de mover, ´rep´ de repetição e assim por diante.
Pode-se editar o código de máquina usando [[Editor hexadecimal|editores hexadecimais]], que irão exibir o código de máquina como uma sequência de bytes em hexadecimal.


{{referências}}
=== Exemplo de programa "Olá Mundo" para MS-DOS ===
<pre>
B4 03 CD 10 B0 01 B3 0A B9 0B 00 BD 13 01 B4 13
CD 10 C3 4F 69 20 6D 75 6E 64 6F 21 0D 0A
</pre> .


== Ver também ==
== Ver também ==
* [[Linguagem de alto nível]]
* [[Linguagem de alto nível]]
* [[Linguagem de baixo nível]]
* [[Assembly]]
== Ligações externas ==
* {{link|2=http://ref.x86asm.net/coder32.html|3=Referência de opcodes da arquitetura x86|idioma=en}}
{{referências}}


{{Esboço-informática}}
{{Portal3|Tecnologias de informação}}
{{Portal3|Tecnologias de informação}}



Edição atual tal como às 09h10min de 28 de julho de 2019

Predefinição:Execução de Programa

Bootloader em código de máquina que exibe o texto "Hello World!" na cor verde.

Um programa em código de máquina consiste de uma sequência de bytes que correspondem a instruções a serem executadas pelo processador. As instruções do processador, chamadas de opcodes, são representadas por valores em hexadecimal.[1]

Programação em código de máquina

Para se programar em código de máquina, deve-se obter os códigos de instruções do processador utilizado contendo opcodes, operandos e formatos de cada instrução.

Por esse motivo foi criada uma linguagem de programação chamada Assembly, composta de códigos mnemônicos que expressam as mesmas instruções do processador, embora escritos em acrônimos da língua inglesa, tais como mov ou rep, em vez de opcodes.

Formato da instrução

Figura 2.1 do Intel® 64 and IA-32 Architectures Developer's Manual: Vol. 2A

Uma instrução em código de máquina consiste em uma sequência de bytes, onde cada byte significa algo para o processador. Instruções da arquitetura IA-32 são consistidas por[2]:

  • Prefixos opcionais. Onde pode-se usar nenhum prefixo ou um de cada um dos quatro grupos existentes.
  • Bytes primários do opcode. Onde o opcode pode ter um, dois ou três bytes de tamanho.
  • Se requerido, também pode ter o byte ModR/M. Esse byte consiste em três campos de informações:
    • O campo mod que combinado com o campo R/M pode formar 32 valores diferentes: Oito registradores e 24 modos de endereçamento.
    • O campo reg/opcode especifica o número do registrador ou mais três bits de informação do opcode. O propósito desse campo é especificado no opcode primário.
    • O campo R/M, que pode ser usado para um registrador como operando ou pode ser combinado com o campo mod para especificar um modo de endereçamento.
  • Se requerido, pode ter também o byte SIB que serve para especificar três informações sobre endereçamentos de memória. Onde essas informações ficam nos seguintes campos:
    • O campo scale serve para especificar uma escala de endereçamento.
    • O campo index especifica o número do registrador utilizado como índice de acesso ao endereço.
    • E o campo base especifica o número do registrador utilizado como endereço base.

Essas informações escritas em Assembly seguindo a sintaxe da Intel, ficam no seguinte formato:

mov dword [ebp + ebx*4], eax

Onde ebx é o registrador index, ebp é o registrador base e 4 a escala. Onde escala pode ser os valores 1, 2, 4 ou 8.

  • Algumas formas de endereçamento precisam de um deslocamento imediato que fica logo após o byte ModR/M, ou o byte SIB se estiver presente. Caso um deslocamento imediato seja necessário, este pode ter um tamanho de um, dois ou quatro bytes.
  • Se uma instrução especifica um operando imediato, o operando fica após todos os bytes de deslocamento. E pode ter o tamanho de um, dois ou quatro bytes.

Prefixos

Os prefixos são bytes inseridos logo antes de um opcode, que serve para alterar a forma com que uma instrução é executada. Os prefixos são opcionais e indiferente da ordem, isto é, não faz diferença em que ordem eles são colocados. Além disso, só pode ser utilizado em uma instrução apenas um prefixo de cada grupo. Não sendo possível incluir dois ou mais prefixos pertencentes do mesmo grupo.[2]

  • Grupo 1
    • Prefixos de bloqueio e repetição
      • F0h - Prefixo LOCK, utilizado para garantir o uso exclusivo da memória compartilhada.[3]
      • F2h - Prefixo REPNE/REPNZ.
      • F3h - Prefixo REP ou REPE/REPZ.
  • Grupo 2
    • Prefixos de sobreposição de segmentos
      • 2Eh - Segmento CS.
      • 36h - Segmento SS.
      • 3Eh - Segmento DS.
      • 26h - Segmento ES.
      • 64h - Segmento FS.
      • 65h - Segmento GS.
    • Prefixos Branch Hints - Usados em instruções de pulo condicional para se aproveitar da tecnologia Branch prediction.
      • 2Eh - Caminho pouco provável. (usado somente em instruções de pulo condicional)
      • 3Eh - Caminho provável. (usado somente em instruções de pulo condicional)
  • Grupo 3
    • 66h - Prefixo para sobreposição do tamanho do operando.
  • Grupo 4
    • 67h - Prefixo para sobreposição do tamanho do endereço.

Visualização de programas em linguagem de máquina

Um programa em código de máquina é um arquivo binário. Como tal, não pode ser visualizado em um editor de texto.

Pode-se editar o código de máquina usando editores hexadecimais, que irão exibir o código de máquina como uma sequência de bytes em hexadecimal.

Exemplo de programa "Olá Mundo" para MS-DOS

B4 03 CD 10 B0 01 B3 0A B9 0B 00 BD 13 01 B4 13
CD 10 C3 4F 69 20 6D 75 6E 64 6F 21 0D 0A

.

Ver também

Ligações externas

Referências

talvez você goste