Comment on page
Hello World em x86
Explicação de um Hello World em Assembly x86
Usando códigos como exemplo, é recomendável antes de mais nada entender conceitos básicos do Assembly x86, como a instrução
mov
.Usando por exemplo esse programa:
;; Programa Hello World
section .text
global _start
_start:
mov edx,len ;comprimento da mensagem
mov ecx,msg ;mensagem a ser escrita
mov ebx,1 ;descritor de arquivo (stdout)
mov eax,4 ;número da system call
; (sys_write)
int 0x80 ;call kernel
mov eax,1 ;numero da syscall
; (sys_exit)
int 0x80 ;call kernel
section .data
msg db 'Hello, world!',0xa ;nossa string lindona
len equ $ - msg ;comprimento da lindona
Inicia com um comentário, marcado a partir de um
;
como você pode ver.É necessário especificar seções do código. Uma vez que o Assembly vai ser carregado diretamente na memória, você precisa especificar o que é o fragmento
text
(instruções) e o que é o fragmento data
(código não executável, usado para guardar strings e algumas variáveis, etc.). Como vocẽ pode ver, define-se um rótulo (label na forma culta) global _start
. Isso é necessário para ser possível definir o ponto de entrada do código (É um rótulo padrão).Vamos olhar agora a seção
.data
. Primeiramente ela declara um "define byte" (db
) que nós chamamos de msg
, com a string que queremos imprimir, juntamente com 0xa
, que é o caractere de nova linha, (equivalente ao \n
no C, por exemplo). Na próxima linha, definimos uma variável len
que representa o comprimento da string, isto é, o endereço atual da memória onde está a instrução (representado por $
) subtraído do começo da string (msg
).Voltando agora para o rótulo
_start
(também chamado de função nesse caso), nas primeiras 4 linhas nós acabamos de armazenar as variáveis nos registradores edx
e ecx
, depois nós colocamos o valor 1 em ebx
e 4 em eax
. Isso significa que, uma vez que queremos escrever alguma coisa na stdout
(ou saída padrão), nós usamos a syscall write
, que pede o argumento fd
(descritor de arquivo) passado no registrador ebx
como uma convenção, como visto em System Calls Reference. Então a int
errupção 0x80 será chamada (isso é uma syscall), que irá imprimir "Hello, world!" no terminal.No final, o registrador
eax
terá o valor 1, significando a syscall "exit". Então será chamado através de int 0x80
, saindo do programa.No caso de nós quisermos colocar um
return 0
no final do código, nós poderíamos colocar apenas mov ebx, 0
logo antes da syscall.Supondo que temos um código
hello.asm
, podemos montá-lo comnasm -f elf hello.asm
Fazendo isso nós especificamos que o formato do arquivo será um
elf
(32bits) e um novo objeto hello.o
será produzido.Ainda assim, esse não é nosso arquivo executável. Para fazer um ainda precisamos utilizar o comando
ld
(link-editor) para ligar o objeto com as bilbiotecas do sistema, o que pode ser feito facilmente:ld -s -o hello hello.o -m elf_i386
Isso simplesmente liga o objeto gerado para um executável
hello
, que tem o formato elf_i386
. No caso de qualquer erro acontecer, verifique se você tem 32bits glibc
no seu sistema operacional.Então, execute-o simplesmente usando
./hello
E é isso, temos nosso Hello World! OwO
Last modified 3yr ago