Ver la versión completa : ¿Que hacen estas lineas de codigo?
anibarro
07/02/2008, 15:22
Buenas, me he encontrado unas lineas en asm, y aunque mas o menos me imagino lo que hacen, necesito saberlo exactamente o una funcion en C que haga lo mismo :P
La funcion es esta:
int shl10idiv (int x, int y);
#pragma aux shl10idiv = \
" mov edx, eax " \
" shl eax, 10 " \
" sar edx, 22 " \
" idiv ebx " \
parm [eax] [ebx] \
modify exact [eax edx] \
value [eax];
Muchas gracias ;)
Edit: He encontrado esto:
// This is the only Watcom C/C++ specific part of the function. These
// instructions take a 26:6 bit fixed point number and converts it
// to 32:32 bit. Then divides it with another 16:16 bit fixed point
// number. The result is 16:16 bit. This must be done in asm where we
// can do 64/32 bit divides.
Ahora se lo que hace, pero no se como hacerlo en C, o al menos algo parecido que sirva :S
Oh, vaya, ya me has fastidiado el problema. Es como mirar las soluciones de los pasatiempos. Era más chulo antes, cuando no se sabía la máquina ni el compilador del código ensamblador :) Ya había supuesto por mi cuenta que era un Intel 32 bits compilado con Watcom. En realidad creía que la entrada x sería de 22:10 bits, así que debo de estar perdiendo facultades :D
Aunque me he pegado con muchos ensambladores, de C sé entre poco y nada así que no puedo ayudarte. ¿Has mirado si este código simple funciona?
int shl10idiv(int x, int y){
long d;
d=x<<26;
return (int)(d/y);
}
Suponiendo que en el compilador que estés usando tenga long de 64bits e int de 32bits, claro está. Pero de esto no tengo suficientes datos :)
Acabo de mirar: en C los longs parecen tener 32 bits siempre. Supongo que por eso el autor original hizo la función en ensamblador :D Es posible que en tu caso tengas que reescribir la función al ensamblador de tu máquina y compilador objetivo.
anibarro
07/02/2008, 19:40
Uff..gracias por contestar, aunque sea para decirme que no se puede xD
Queria hacerlo lo mas generico posible, sin entrar en cosas especificas de cada procesador, pero ya veo que va a ser dificil :S
La cuestion es que me dan un numero en 26:6, otro en 16:16, y tengo que sacar un 16:16...
Estoy pensando en pasar los dos a float normal y corriente, dividir y luego pasar el resultado a 16:16, ira lentisimo pero al menos me sirve para saber si funciona. El problema es que de momento da errores por todos lados, a ver si los voy arreglando y puedo probar eso que pones ;) En C suele usarse "long long" para definir variables de 64bits, en casi todos los compiladores se puede, espero que en este tambien xD
Un saludo
int shl10idiv(int x, int y)
{
return ((int64_t)(x << 10)) / y;
}
el código original asm hace un shift 10 bits a la izquierda del primer operando, y lo divide por el segundo.
deberas incluir el fichero de cabecera stdint.h para disponer del tipo int64_t o tambien puedes usar long long si tu compilador lo soporta (es mejor decirle explicitamente que el resultante del shift tiene que ser de 64 bits si no quieres encontrarte sorpresas).
bulbastre
08/02/2008, 17:02
Oh, vaya, ya me has fastidiado el problema. Es como mirar las soluciones de los pasatiempos. Era más chulo antes, cuando no se sabía la máquina ni el compilador del código ensamblador :) Ya había supuesto por mi cuenta que era un Intel 32 bits compilado con Watcom. En realidad creía que la entrada x sería de 22:10 bits, así que debo de estar perdiendo facultades :D
Enhorabuena ,este es el párrafo más friki / geek que he leído en lo que va de año.
anibarro
08/02/2008, 17:07
Muchas gracias ^^ Es para compilarlo con eVC++, y justo esos tipos de datos los soporta :D A ver si arreglo los miles de fallos que me da y puedo probarlo
Powered by vBulletin® Version 4.2.5 Copyright © 2025 vBulletin Solutions Inc. All rights reserved.