fstps em 32 e 64 bits

1. fstps em 32 e 64 bits

???
gokernel

(usa Linux Mint)

Enviado em 08/09/2017 - 10:58h

Olá !


Sem bla bla bla ... vou direto.

Tenho o seguinte código muitíssimo reduzido mesmo em 32 bits:


#include <stdio.h>

typedef union TValue TValue;

union TValue {
long l; //: type long integer
float f; //: type float
char *s; //: type pointer of char
void *p; //: type pointer
};

TValue ret;

void funcao (void) {
#ifdef WIN32

asm ("fstps _ret");

#endif
#ifdef __linux__

asm ("fstps ret");

#endif
}


int main (void) {

// OBS: NAO EXECUTAR POIS ERRA: ;)
//
funcao();

printf ("Saindo Com Sucesso !!!\n");

return 0;
}


Essa parada é um retorno de uma função com retorno ( float ).

PERGUNTA:
Em 64 bits o que seria o equivalente a isso ( fstps ) ?

OBS1: o código completo está funcionando em 32 BITS, ainda não testei em 64 bits ... não coloquei um código maior para evitar confusão.

Grato !.


;


  


2. Re: fstps em 32 e 64 bits

Paulo
paulo1205

(usa Ubuntu)

Enviado em 08/09/2017 - 14:03h

Use “fstpl” para o equivalente a double, e “fstpt” para long double.


3. Re: fstps em 32 e 64 bits

Paulo
paulo1205

(usa Ubuntu)

Enviado em 08/09/2017 - 14:38h

Contudo, se você estiver portanto código para arquitetura AMD64, cuidado com o que você pretende fazer. O default[/b] do GCC para float e double não é usar os registradores compatíveis com o 80387, mas sim os registradores de [i]media, xmm0 a xmm15 e as instruções que trabalham com esses registradores. Eu demorei a conseguir gerar código que usasse os registradores tradicionais (na verdade, demorei a descobrir a opção -mfpmath=387), que só é usado por default com dados do tipo long double.

Adicionalmente, a sintaxe da instrução fstp em Assembly no dialeto Intel Intel é “fstp QWORD PTR var” para double, e “fstp TBYTE PTR var” (eu nunca tinha visto esse “TBYTE”).


4. Re: fstps em 32 e 64 bits

???
gokernel

(usa Linux Mint)

Enviado em 08/09/2017 - 15:55h


Valeu "paulo1205" pelo retorno !


O meu código é muito similar(reduzi ao máximo para demonstrar) a esse abaixo:


//-------------------------------------------------------------------
//
// Funcao Retorna Float:
//
// FILE:
// return_float.c
//
// COMPILE:
// gcc return_float.c -o return_float -Wall
//
//-------------------------------------------------------------------
//
#include <stdio.h>

#define UCHAR unsigned char

typedef union TValue TValue;

union TValue {
long l; //: type long integer
float f; //: type float
char *s; //: type pointer of char
void *p; //: type pointer
};

UCHAR code[50];
UCHAR *p = code;
TValue arg[10];
TValue ret;


float soma (float a, float b)
{
return a+b;
}

void funcao (void)
{
TValue (*func) ();

*(void**)p = soma;
p += sizeof(void*);

func = *(void**)(code); // func = soma

// 2501.000000
//
arg[0].f = 1000.50;
arg[1].f = 1500.50;

// executa a funcao
//
func (arg[0], arg[1]); // return float: 2501.000000

//
// aqui captura o resultado float
//
#ifdef WIN32
asm ("fstps _ret");
#endif
#ifdef __linux__
asm ("fstps ret");
#endif
}

int main (void)
{
funcao();
printf ("\nSaindo Com Sucesso - ret: %f\n", ret.f); // 2501.0000
return 0;
}


OBS: Esse código testei apenas no Windows em 32 bits, acho que no Linux 32 bits também funciona ... não testei no Linux.

O meu desafio é substituir a parte que usa assembly para tornar o código muito portável.



5. Re: fstps em 32 e 64 bits

???
gokernel

(usa Linux Mint)

Enviado em 08/09/2017 - 16:18h


Caramba ! ... quando estava já pronto para desligar o note "uma luz" e o resultado que queria... Glória a Deus !!!

Sim é assim que vou usar parcialmente modificado esse código.


//-------------------------------------------------------------------
//
// Funcao Retorna Float:
//
// FILE:
// return_float.c
//
// COMPILE:
// gcc return_float.c -o return_float -Wall
//
//-------------------------------------------------------------------
//
#include <stdio.h>

#define UCHAR unsigned char

typedef union TValue TValue;

union TValue {
long l; //: type long integer
float f; //: type float
char *s; //: type pointer of char
void *p; //: type pointer
};

UCHAR code[50];
UCHAR *p = code;
TValue arg[10];
TValue ret;


float soma (float a, float b)
{
return a+b;
}

void funcao (void)
{
float (*func) ();

*(void**)p = soma;
p += sizeof(void*);

func = *(void**)(code); // func = soma

// 2501.000000
//
arg[0].f = 1000.50;
arg[1].f = 1500.50;

// executa a funcao
//
ret.f = func (arg[0], arg[1]); // return float: 2501.000000

/*
// PRONTO NAO USA MAIS ASSEMBLY ...
//
// aqui captura o resultado float
//
#ifdef WIN32
asm ("fstps _ret");
#endif
#ifdef __linux__
asm ("fstps ret");
#endif
*/
}

int main (void)
{
funcao();
printf ("\nSaindo Com Sucesso - ret: %f\n", ret.f); // 2501.0000
return 0;
}








Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts