Adiel Fontes
Adiel Fontes03/09/2026 12:34
Compartilhe

Implementação de uma calculadora gráfica em arquitetura x64 puro Assembly

    image

    Resumo

    Este trabalho apresenta o desenvolvimento e a implementação de uma calculadora com interface gráfica nativa para sistemas operacionais Windows, desenvolvida inteiramente em linguagem Assembly para arquitetura x86-64. Diferente de abordagens convencionais que utilizam bibliotecas de alto nível e ambientes de tempo de execução (Runtime C/C++), este programa interage diretamente com a interface de programação de aplicativos do Windows (Windows API), demonstrando em detalhe a estrutura de janelas, o fluxo de mensagens, a criação de controles e a manipulação de dados em nível de arquitetura. O resultado é um executável de tamanho reduzido, sem dependências externas e que ilustra os princípios fundamentais de funcionamento de aplicações gráficas na plataforma Windows.

    Palavras-chave: Assembly x86-64; Windows API; Interface Gráfica; Processamento de Mensagens; Programação de Baixo Nível.

    Introdução

    A programação de aplicações gráficas é comumente realizada por meio de linguagens de alto nível e frameworks que abstraem a complexidade do sistema operacional. Embora essa prática seja eficiente para o desenvolvimento de software produtivo, ela oculta os mecanismos fundamentais que regem a criação de janelas, a comunicação com o sistema operacional e a organização da memória e da pilha de execução.

    A linguagem Assembly permite ao programador compreender e controlar diretamente os recursos do processador e do sistema operacional. Em especial, a arquitetura x86-64 apresenta um conjunto de registradores e uma convenção de chamada bem definida para a plataforma Windows, que possibilita a construção de aplicações gráficas funcionais por meio de chamadas diretas às funções do sistema.

    Este trabalho tem como objetivo apresentar o projeto e a implementação de uma calculadora gráfica desenvolvida puramente em Assembly x64, utilizando exclusivamente funções da Windows API. Discutem-se a estrutura da aplicação, a convenção de chamada utilizada, o tratamento de mensagens e a lógica de funcionamento, bem como as dificuldades encontradas e as soluções adotadas durante o desenvolvimento.

    Fundamentos Teóricos

    A Plataforma Windows e a Interface Gráfica

    As aplicações com interface gráfica no Windows seguem um modelo orientado a eventos. O sistema operacional notifica a aplicação sobre ações do usuário (cliques, digitação, movimentação da janela) por meio de mensagens que são enfileiradas e processadas pela própria aplicação.

    Para que uma janela exista, é necessário:

    1.   Registrar uma classe de janela informando características e procedimento de tratamento de mensagens;

    2.   Instanciar a janela principal;

    3.   Executar um laço de leitura e despacho de mensagens.

    Convenção de Chamada na Arquitetura x64 Windows

    A plataforma Windows para processadores de 64 bits adota uma convenção de chamada padronizada:

    • Os quatro primeiros parâmetros são passados pelos registradores: RCX, RDX, R8 e R9;
    • Parâmetros subsequentes são enviados por meio da pilha, com deslocamentos consecutivos;
    • Antes de cada chamada de função, a pilha deve ser alinhada em endereços múltiplos de 32 bytes;
    • A função chamada preserva os registradores RBX, RBP, RSI, RDI, R12–R15, devolvendo-os inalterados ao chamador.

    Funções Essenciais da Windows API Utilizadas

    Função

    Propósito

    GetModuleHandleA

    Obtém o endereço da instância do programa

    RegisterClassExA

    Registra as características da classe de janela

    CreateWindowExA

    Cria a janela principal e controles (botões, campos de texto)

    ShowWindow / UpdateWindow

    Exibe e redesenha a janela

    GetMessageA

    Lê mensagens da fila de eventos do sistema

    TranslateMessage

    Converte mensagens de teclado

    DispatchMessageA

    Envia mensagens ao procedimento da janela

    SetWindowTextA

    Atualiza o texto exibido no visor

    PostQuitMessage

    Encerra o laço de mensagens

    DefWindowProcA

    Processa mensagens não tratadas pela aplicação

    Metodologia e Desenvolvimento

    Estrutura Geral do Programa

    A aplicação foi organizada em quatro etapas principais:

    1. Inicialização: obtenção da instância do programa e registro da classe de janela;
    2. Criação da Janela Principal e Controles: instanciação da janela, do visor e dos botões numéricos e de operação;
    3. Laço de Mensagens: leitura, tradução e despacho contínuo de eventos do sistema;
    4. Procedimento de Janela: tratamento de criação, comandos e encerramento.

    Tratamento de Mensagens

    O procedimento WindowProc é o núcleo lógico da aplicação. Ele recebe mensagens enviadas pelo sistema e responde conforme o tipo:

    • WM_CREATE: acionada no momento da criação da janela. Nesta etapa, instancia-se o campo de exibição (visor alinhado à direita, somente leitura) e cada um dos 16 botões organizados em quatro linhas: dígitos de 0 a 9, ponto decimal, operadores (+ − × /), botão de limpeza (C) e botão de igualdade (=). Cada botão é criado por chamada direta à função CreateWindowExA, com posicionamento e dimensões definidos em coordenadas de tela.
    • WM_COMMAND: acionada quando o usuário clica em um botão. O identificador do controle é extraído e comparado para executar a ação correspondente:
    • Dígitos: concatenam o caractere ao número exibido;
    • Ponto decimal: insere separador, evitando repetição;
    • Operadores: convertem o valor exibido em inteiro e armazenam o valor e o tipo de operação;
    • Botão de igualdade: realiza a operação aritmética, trata divisão por zero e converte o resultado de volta para texto;
    • Botão C: reinicia todos os valores e exibe o número zero.
    • WM_DESTROY: encerra a aplicação corretamente ao fechar a janela.

    Mensagens não tratadas são encaminhadas à função padrão DefWindowProcA.

    Conversão de Dados

    Como a API do Windows trabalha com texto e os cálculos exigem valores numéricos, foram implementadas duas rotinas auxiliares:

    • StringParaInteiro: percorre caractere por caractere, convertendo o texto em valor inteiro com sinal;
    • InteiroParaString: converte o resultado numérico de volta para sequência de caracteres, tratando sinal negativo e valor zero.

    Compilação e Linkagem

    O código foi montado com o NASM no formato binário de 64 bits e posteriormente vinculado ao executável por meio do GCC (MinGW-w64), que realiza a ligação com as bibliotecas do sistema user32.dll (interface gráfica) e kernel32.dll (funções básicas).

    bash

    nasm -f win64 calc.asm -o calc.o

    gcc calc.o -o calc.exe -mwindows -luser32 -lkernel32

    Resultados e Discussão

    Tamanho e Independência de Runtime

    O executável gerado possui aproximadamente 15 KB e não exige bibliotecas adicionais ou ambientes de tempo de execução instalados no sistema. Essa característica contrasta com aplicações compiladas em linguagens de alto nível, que frequentemente dependem de bibliotecas externas e apresentam tamanho significativamente maior.

    Desafios e Correções

    Durante o desenvolvimento, foram identificados problemas diretamente relacionados à programação em nível de arquitetura:

    • Alinhamento da Pilha: chamadas a funções da Windows API exigem que a pilha esteja alinhada em 32 bytes antes de cada instrução call. O não cumprimento dessa regra causava falhas silenciosas e fechamento inesperado da janela;
    • Convenção de Chamada: o uso incorreto de registradores e deslocamentos na pilha resultava em parâmetros inválidos enviados às funções, impedindo a criação de controles;
    • Sintaxe e Tamanho de Operandos: especificadores de tamanho redundantes em instruções de movimentação causavam erros de montagem, exigindo estrita observância às regras do montador NASM.

    Funcionamento Final

    A versão corrigida apresenta janela visível imediatamente ao ser executada, com visor funcional e todos os botões reagindo corretamente aos cliques. As quatro operações aritméticas funcionam conforme esperado, com tratamento de erro para divisão por zero e reinicialização completa ao acionar o botão de limpeza.

    Conclusão

    Este trabalho demonstrou a viabilidade e a complexidade da construção de uma aplicação gráfica funcional utilizando exclusivamente linguagem Assembly e chamadas diretas ao sistema operacional. Foi possível compreender em detalhe a estrutura de janelas, o fluxo de mensagens, a convenção de chamada da arquitetura x64 Windows e a forma como o sistema operacional interage com as aplicações.

    Embora essa abordagem demande conhecimento aprofundado da arquitetura do processador e das funções do sistema, ela oferece total controle sobre o comportamento do programa, resultando em executáveis extremamente leves e sem dependências externas. Os desafios encontrados — especialmente quanto ao alinhamento da pilha e à passagem de parâmetros — evidenciam a importância de dominar os fundamentos da arquitetura de computadores para o desenvolvimento de software robusto.

    Como trabalhos futuros, sugere-se a ampliação da precisão numérica com suporte a ponto flutuante, a implementação de funções matemáticas adicionais, o suporte a entrada por teclado e o aprimoramento da apresentação visual por meio de recursos gráficos avançados da API.

    Referências

    1. RUSSINOVICH, M. E.; SOLOMON, D. A. Windows Internals: Parte 1. 7. ed. Microsoft Press, 2021.
    2. FOG, A. Optimizing Subroutines in Assembly Language. Disponível em: https://www.agner.org/optimize/, 2024.
    3. MICROSOFT. Windows API Documentation. Disponível em: https://learn.microsoft.com/windows/win32/api/, 2026.
    4. NASM Development Team. NASM — The Netwide Assembler Documentation. Disponível em: https://nasm.us/, 2026.
    5. MINGW-W64 Project. MinGW-w64: GCC for Windows. Disponível em: https://www.mingw-w64.org/, 2026.

    Repositório:https://github.com/fydelis2025/Calculadora_ASM

    Compartilhe
    Comentários (0)