Jump to content

Código em ASM com gcc


Eduardo Bittencourt

Recommended Posts

Posted

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

 

  • 1 month later...
  • 2 weeks later...
Posted

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.

  • 2 months later...
Posted

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

Archived

This topic is now archived and is closed to further replies.

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...