Jump to content
Sign in to follow this  
Euler Neto

Dica para Conversão de C para Assembly

Recommended Posts

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

  • Curtir 2

Share this post


Link to post
Share on other 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.

Edited by Felipe.Silva
  • Curtir 1

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...