ASM: troca stack usando int/long.

1. ASM: troca stack usando int/long.

???
gokernel

(usa Linux Mint)

Enviado em 01/07/2014 - 11:42h


Olá pessoal !

Tenho esse código em Assembly( AT&T sintax ):



/*
**-------------------------------------------------------------------
**
** COMPILE:
** gcc prog.c -o prog -Wall
**
**-------------------------------------------------------------------
*/
#include <stdio.h>

int i;

//
// i = 20 / 5; // 4
//
void funcao (void)
{
asm ("push $20"); // primeiro numero MAIOR
asm ("push $5"); // agora numero menor

//---------------------------------
//
// troca: (%esp), 4(%esp)
//
//---------------------------------
asm ("mov (%esp), %eax");
asm ("mov 4(%esp), %edx");
asm ("mov %eax, 4(%esp)");
asm ("mov %edx, (%esp)");
//---------------------------------

asm ("pop %eax");
asm ("cltd");
asm ("idivl (%esp)");
asm ("mov %eax,(%esp)");

#ifdef _WIN32
asm ("pop _i");
#endif
#ifdef __linux__
asm ("pop i");
#endif
}

int main (void)
{
funcao();
printf ("\nresult i: %d\n", i); // 4
return 0;
}



Alguém sabe se existe um OPCODE assembly que faça a troca de ( (%esp), 4(%esp) ) usando int/long ?


Algo similar a usando float:



asm ("fxch %st(1)");



Grato !



  


2. Re: ASM: troca stack usando int/long.

Paulo
paulo1205

(usa Ubuntu)

Enviado em 02/07/2014 - 17:47h

A instrução mais lógica seria xchg, mas ela exige que pelo menos um dos operandos seja um registrador.

Não estou muito familiarizado com a sintaxe do Assembly, mas não serviria algo como
; Swap tradicional: (c=a; a=b; b=c;)
movl (%esp), %eax
movl 4(%esp), (%esp)
movl %eax, 4(%esp)

,
; Parecido, mas usando XCHG
movl (%esp), %eax
xchgl 4(%esp), %eax
movl %eax, (%esp)

, ou ainda
; Com POP e PUSH
pop %eax
xchgl (%esp), %eax
push %eax

? (Note que eu não sei qual ocuparia menos ciclos de relógio.)

De todo modo, não seria melhor empilhar os operandos já na ordem desejada?


3. Re: ASM: troca stack usando int/long.

???
gokernel

(usa Linux Mint)

Enviado em 02/07/2014 - 21:13h

@paulo:
"De todo modo, não seria melhor empilhar os operandos já na ordem desejada?"

Nao, o que estou fazendo eh uma linguagem de alto nível e requer a lógica de colocar o numero maior primeiro.

O que postei foi algo bem simples para apresentar "o problema".

Na verdade encontrei autra solução melhor:
Faço a troca direto na compilação do código... economizando tamanho do código gerado e ao mesmo tempo ganhando em velocidade...

OBS: não vou postar o código real pois ficaria muito mais difícil de entender o "problema".



4. Re: ASM: troca stack usando int/long.

Paulo
paulo1205

(usa Ubuntu)

Enviado em 02/07/2014 - 22:55h

gokernel escreveu:

@paulo:
"De todo modo, não seria melhor empilhar os operandos já na ordem desejada?"

Nao, o que estou fazendo eh uma linguagem de alto nível e requer a lógica de colocar o numero maior primeiro.

O que postei foi algo bem simples para apresentar "o problema".

Na verdade encontrei autra solução melhor:
Faço a troca direto na compilação do código... economizando tamanho do código gerado e ao mesmo tempo ganhando em velocidade...


Em outras palavras: você está empilhando os argumentos já na ordem desejada, ainda que por obra do seu compilador.