Repositório acadêmico da disciplina Interface Hardware e Software, voltado ao estudo da relação entre programas, sistema operacional, compiladores e hardware. O objetivo é compreender como um código escrito em linguagem de alto nível é traduzido, carregado, executado e analisado em uma arquitetura real.
O foco principal está em programação de baixo nível, Assembly AMD64, binários ELF, chamadas de sistema, registradores, memória, compilação e análise de desempenho.
A disciplina de Interface Hardware e Software busca aproximar dois níveis fundamentais da computação:
- o software, representado por programas, linguagens, compiladores e sistemas operacionais;
- o hardware, representado por processadores, registradores, memória, instruções de máquina e dispositivos.
Neste repositório, os estudos são organizados em exemplos práticos que ajudam a entender o caminho entre o código-fonte e a execução no processador.
- Arquitetura x86-64 / AMD64;
- registradores de uso geral, como
rax,rbx,rcx,rdx,rdi,rsi, entre outros; - instruções básicas de movimentação e aritmética, como
mov,add,sub,imul,divexor; - pilha de execução, chamadas de função e convenções de chamada;
- organização da memória em seções como
.text,.datae.bss.
- escrita de programas simples em Assembly;
- uso de syscalls no Linux;
- finalização de programas com a syscall
exit; - manipulação direta de registradores;
- diferença entre código Assembly, código de máquina e executável.
- compilação de programas em C com
gcceclang; - geração e análise de código Assembly;
- geração de LLVM IR;
- análise do processo de tradução entre código-fonte, representação intermediária, Assembly e binário.
- estrutura de arquivos executáveis ELF;
- uso de
objdumppara inspecionar executáveis; - leitura de trechos de disassembly;
- comparação entre código C, Assembly gerado e instruções executadas.
- comparação entre implementações iterativas e recursivas;
- uso de
gprofpara análise de chamadas de função; - uso de
perfpara análise de desempenho em nível mais próximo do hardware; - observação de tempo de execução, chamadas, instruções e possíveis gargalos.
Este repositório reúne atividades e experimentos relacionados a:
| Tipo de conteúdo | Descrição |
|---|---|
| Exemplos em Assembly AMD64 | Programas simples para praticar instruções, registradores e syscalls. |
| Programas em C | Códigos usados para observar compilação, otimização e desempenho. |
| Saídas de ferramentas | Resultados de objdump, gprof, perf e outras ferramentas de análise. |
| LLVM IR | Representações intermediárias geradas a partir de programas em C. |
| Estudos de desempenho | Comparações entre diferentes formas de implementação, como funções iterativas e recursivas. |
| Ferramenta | Finalidade |
|---|---|
gcc |
Compilar programas em C e Assembly no ambiente GNU/Linux. |
clang |
Compilar C e gerar LLVM IR. |
nasm |
Montar programas Assembly com sintaxe Intel/NASM. |
ld |
Linkar arquivos objeto gerados pelo assembler. |
objdump |
Inspecionar e desmontar executáveis. |
gdb |
Depurar programas e observar registradores/memória. |
gprof |
Gerar relatórios de profiling baseados em instrumentação. |
perf |
Medir desempenho usando eventos do sistema e do processador. |
strace |
Observar chamadas de sistema realizadas por um programa. |
Os códigos foram desenvolvidos e testados em ambiente Linux Ubuntu, incluindo uso via WSL no Windows.
Ambiente recomendado:
- Ubuntu ou outra distribuição Linux;
- terminal Bash;
gcc,clang,nasm,binutils,gdb,perfegprofinstalados.
Para instalar parte das ferramentas no Ubuntu:
sudo apt update
sudo apt install build-essential nasm clang llvm binutils gdb linux-tools-common linux-tools-genericObservação: em ambientes WSL, algumas funções do
perfpodem ter limitações dependendo da configuração do sistema.
git clone https://github.com/thejosephantony/InterfaceHardwareSoftware.git
cd InterfaceHardwareSoftwaregcc -Wall -g arquivo.c -o programa
./programaCom profiling usando gprof:
gcc -Wall -g -pg arquivo.c -o programa
./programa
gprof ./programa gmon.out > resultado.txtclang -S -emit-llvm arquivo.c -o arquivo.llobjdump -d -M intel programaPara desmontar todas as seções do binário:
objdump -D -z -M intel programanasm -f elf64 arquivo.asm -o arquivo.o
ld arquivo.o -o programa
./programaPara visualizar o código de saída do programa:
echo $?Caso o arquivo use sintaxe compatível com o gcc/GNU assembler:
gcc -no-pie arquivo.s -o programa
./programaUm programa Assembly mínimo em Linux pode encerrar sua execução usando a syscall exit:
section .text
global _start
_start:
mov rax, 60 ; número da syscall exit no Linux x86-64
mov rdi, 0 ; código de saída
syscall ; chamada ao kernelNesse exemplo:
raxrecebe o número da chamada de sistema;rdirecebe o primeiro argumento da syscall;syscalltransfere o controle para o kernel.
Para comparar diferentes implementações, como fatorial iterativo e fatorial recursivo, podem ser usadas ferramentas como gprof e perf.
Exemplo com perf:
perf stat ./programaExemplo com time:
time ./programaEssas ferramentas ajudam a observar diferenças entre:
- tempo real de execução;
- tempo gasto em modo usuário;
- tempo gasto em chamadas de sistema;
- quantidade de chamadas de função;
- impacto de otimizações do compilador.
Durante os estudos, alguns conceitos aparecem com frequência:
- Assembly: representação textual de instruções de máquina;
- código de máquina: instruções binárias executadas pelo processador;
- ELF: formato comum de executáveis em sistemas Linux;
- ABI: conjunto de regras para chamadas de função, passagem de parâmetros e uso da pilha;
- syscall: mecanismo usado por programas para solicitar serviços ao kernel;
- profiling: análise do comportamento de execução de um programa;
- LLVM IR: representação intermediária usada pelo ecossistema LLVM.
Este repositório reforça a ideia de que entender a interface entre hardware e software permite:
- escrever programas mais eficientes;
- compreender melhor o funcionamento de compiladores;
- interpretar mensagens e saídas de ferramentas de baixo nível;
- analisar binários e instruções geradas;
- entender a relação entre código, memória, processador e sistema operacional;
- desenvolver uma base mais sólida para sistemas operacionais, arquitetura de computadores, compiladores e segurança.
- Adicionar um
Makefilepara automatizar a compilação dos exemplos; - separar os códigos por temas ou aulas;
- incluir comentários adicionais nos arquivos Assembly;
- documentar comandos usados em cada atividade;
- adicionar exemplos com entrada e saída esperadas;
- incluir relatórios de profiling mais organizados.
Desenvolvido por Joseph Antony como parte dos estudos da disciplina Interface Hardware e Software.