Jump to content
Sign in to follow this  
Eduardo Bittencourt

Código em ASM com gcc

Recommended Posts

Bom,  resolvi postar essa dica simples, acho que a maioria aqui conheça, porém deve ter um ou dois que não conheça, enfim. Para gerar código em asm através do gcc usamos a seguinte linha de comando

Para 64 bits

$ gcc -S masm=intel programa.c

Caso queira em 32 bits

$ gcc -S masm=intel -m32 programa.c

 

A linhas masm=intel, significa, usar o masm com syntax intel. Um ponto interessante é que com esta técnica, você pode ver as seções de memória do código, e muito outras coisas, claro que são coisas simples. Se realmente prefere desassemblar é recomendável usar o objdump, ou gdb, entre outros

 

#include <stdio.h>

long x = 5;

int main(void)
{
     char *cons = "teste";

     return 0;

}

 

Compilei em 64 bits e em 32 bits, e teve diferenças no código, repare;

Output em 64 bits

$cat teste.s

 

	.file	"teste.c"
	.intel_syntax noprefix
	.globl	x;                                 ;variável x é global
	.data
	.align 8
	.type	x, @object
	.size	x, 8;                              ;tamanho de 8 byte
x:
	.quad	5
	.section	.rodata 
.LC0:
	.string	"teste"                      ;essa string é da seção .rodata
	.text
	.globl	main                          ;função main é global,  oh não diga
	.type	main, @function
main:
.LFB0:
	.cfi_startproc
	push	rbp
	.cfi_def_cfa_offset 16
	.cfi_offset 6, -16
	mov	rbp, rsp
	.cfi_def_cfa_register 6
	lea	rax, .LC0[rip]
	mov	QWORD PTR -8[rbp], rax
	mov	eax, 0
	pop	rbp
	.cfi_def_cfa 7, 8
	ret
	.cfi_endproc
.LFE0:
	.size	main, .-main
	.ident	"GCC: (Debian 6.3.0-18) 6.3.0 20170516"
	.section	.note.GNU-stack,"",@progbits

 

Output em 32 bits

$cat teste.s

 

	.file	"teste.c"
	.intel_syntax noprefix
	.globl	x                                  ; variável global
	.data
	.align 4
	.type	x, @object
	.size	x, 4                             ; tamanho de 4 byte
x:
	.long	5
	.section	.rodata
.LC0:
	.string	"teste"
	.text
	.globl	main
	.type	main, @function
main:
.LFB0:
	.cfi_startproc
	push	ebp
	.cfi_def_cfa_offset 8
	.cfi_offset 5, -8
	mov	ebp, esp
	.cfi_def_cfa_register 5
	sub	esp, 16
	call	__x86.get_pc_thunk.ax
	add	eax, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_
	lea	eax, .LC0@GOTOFF[eax]
	mov	DWORD PTR -4[ebp], eax
	mov	eax, 0
	leave
	.cfi_restore 5
	.cfi_def_cfa 4, 4
	ret
	.cfi_endproc
.LFE0:
	.size	main, .-main
	.section	.text.__x86.get_pc_thunk.ax,"axG",@progbits,__x86.get_pc_thunk.ax,comdat
	.globl	__x86.get_pc_thunk.ax
	.hidden	__x86.get_pc_thunk.ax
	.type	__x86.get_pc_thunk.ax, @function
__x86.get_pc_thunk.ax:
.LFB1:
	.cfi_startproc
	mov	eax, DWORD PTR [esp]
	ret
	.cfi_endproc
.LFE1:
	.ident	"GCC: (Debian 6.3.0-18) 6.3.0 20170516"
	.section	.note.GNU-stack,"",@progbits

 

Edited by Eduardo Bittencourt
  • Curtir 1

Share this post


Link to post
Share on other sites

Gostei da dica, cara.

Só queria colaborar com a ferramenta GodBolt. Você coloca o código em C e ele mostra o código em Assembly correspondente. :)

 

GodBolt.png

  • Curtir 1

Share this post


Link to post
Share on other sites

Acho que ambos devem conhecer, mas talvez alguem não conheça.

É possível nessa listagem pedir ao GCC que também adicione comentários ao código referentes ao programa, usando o parâmetro -fverbose-asm.

Outra dica é em vez de escrever -m64/-m32, pode se escrever -march=native, para o compilador optimizar o código para a arquitetura da CPU em questão, assim caso a CPU do computador onde o arquivo será compilado, suportar por exemplo instruções estendidas, o GCC irá usa-las.

Edited by Rick Santos

Share this post


Link to post
Share on other sites

Duas dicas:

Para obter um código mais "enxuto", use uma opção de otimização: Recomendo -O2, porque -O3 é mais agressiva e, às vezes, causa problemas (já tive experiência em que -O3 gerou código mais "lento"!).

Use -masm=intel apenas para gerar o código equivalente em assembly, evite usá-lo quando seu código tiver assembly inline. Prefira o estilo AT&T, neste caso. O motivo é que alguns header files podem implementar funções com assembly inline usando o estilo AT&T (é o caso, por exemplo, do header cpuid.h - Veja a função __get_cpuid_max, por exemplo, em /usr/lib/gcc/x86_64-linux-gnu/5/include/cpuid.h).

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...