Ir para conteúdo

Dica para Conversão de C para Assembly


Euler Neto

Posts Recomendados

  • Apoiador Nibble

Para quem está começando com Assembly e já tem conhecimento em programação, esse site pode facilitar o entendimento, pois converte, em tempo real, um código C para Assembly: http://godbolt.org/

A partir desse compilador online, fiz um compilado de algumas funções básicas para ajudar na hora de ler um código em Assembly e, só de bater o olho, já ter uma idéia de que estrutura se trata. A lista pode ser acessada nesse link: https://mega.nz/#!sVJFTYTL!iNkFOD-5n3UfgjaeaTDkYd8pDzHQvg60vmAaqPEqbNA

Link para o comentário
Compartilhar em outros sites

Hehehe, comigo foi o contrário. Eu já sabia Assembly quando comecei a aprender C, aí eu compilava código em C e lia em Assembly para entender melhor o funcionamento do executável gerado.

O próprio GCC oferece opção para apenas compilar o código, sem montar nem linkar ele. Dessa forma é possível ler o Assembly.Screenshot_13.png.881c27a0ceda88be8981ad7ed0d21e2b.png

 

Só usar:

$ gcc programa.c -o programa.asm -S

# Com sintaxe da Intel
$ gcc programa.c -o programa.asm -S -masm=intel

 

Fica a dica para quem quiser dar uma olhada.
É interessante também usar o objdump para ver o programa depois de linkado.
Opção -d do objdump faz ele disassemblar a seção de código.

Link para o comentário
Compartilhar em outros sites

  • 1 ano depois...
  • 1 mês depois...

Chegando atrasado aqui, mas ai vai um complemento à resposta do @Felipe.Silva:

O GCC, sem otimizações ativadas, gera código bem LERDO e bagunçado. Recomendo usar a opção -O2 também:

$ gcc -O2 -masm=intel -S prog.c # Ele vai gerar o prog.s

Ainda... sem dizer nada, o GCC tende a colocar código para "proteção" da pilha. Para criar uma listagem em asm mais pura prefiro adicionar a opção -fno-stack-protector:

$ gcc -O2 -masm=intel -S -fno-stack-protector prog.c # Ele vai gerar o prog.s

Eis um exemplo simples:

#include <stddef.h>
#include <stdint.h>

uint64_t sum( uint32_t *p, size_t size )
{
  uint64_t s;

  s = 0;
  while ( size-- )
    s += *p++;

  return s;
}

Compilado sem otimizações (retiradas as diretivas):

sum:
  push  rbp
  mov rbp, rsp
  mov QWORD PTR -24[rbp], rdi
  mov QWORD PTR -32[rbp], rsi
  mov QWORD PTR -8[rbp], 0
  jmp .L2
.L3:
  mov rax, QWORD PTR -24[rbp]
  lea rdx, 4[rax]
  mov QWORD PTR -24[rbp], rdx
  mov eax, DWORD PTR [rax]
  mov eax, eax
  add QWORD PTR -8[rbp], rax
.L2:
  mov rax, QWORD PTR -32[rbp]
  lea rdx, -1[rax]
  mov QWORD PTR -32[rbp], rdx
  test  rax, rax
  jne .L3
  mov rax, QWORD PTR -8[rbp]
  pop rbp
  ret

Compilado com otimização -O2:

sum:
  test  rsi, rsi
  je  .L4
  xor edx, edx
  xor eax, eax
.L3:
  mov ecx, DWORD PTR [rdi+rdx*4]
  add rdx, 1
  add rax, rcx
  cmp rdx, rsi
  jne .L3
  rep ret
.L4:
  xor eax, eax
  ret

Note que a segunda compilação não usa o stack frame e usa os registradores ao máximo (com apenas 1 referência à memória)... Acho a segunda mais fácil de entender que a primeira.

Link para o comentário
Compartilhar em outros sites

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

  • Quem Está Navegando   0 membros estão online

    • Nenhum usuário registrado visualizando esta página.
×
×
  • Criar Novo...