Si quieres pues habrimos un hilo y le entramos a los OPCodes estos, asi sale y aprendo un poco mas yo tambien.
Bueno pues "pa luego es tarde" Aquí está el hilo de OPCodes
Salud OS
Escrito 16 diciembre 2008 - 05:40
Bueno tomando el ASM de la mosca:
Tenemos:
asm call GetTickCount // obtenemos el la cantidad de Ticks actual sub eax, [Start] // la restamos Start obteniendo el lapso en milisegundos
Escrito 16 diciembre 2008 - 06:38
Escrito 16 diciembre 2008 - 06:48
Hola
He eliminado mi mensaje, me parece que es un hilo en donde se puede aprender mucho y no esta bien interrumpirlo y mucho menos desvirtuarlo.
Saludos
Escrito 16 diciembre 2008 - 07:17
...
Yo tengo dos preguntas al Maestro: ¿ que es exactamente [Start] en este codigo? ¿EAX retorna con el contenido o resultado que se obtiene de " GetTickCount"?
Un Saludo.
Start: Cardinal; // contendra el momento del "inicio" del juego, lo que nos permitira cronometrar
Escrito 16 diciembre 2008 - 07:25
Escrito 16 diciembre 2008 - 07:27
Hola Fena, si asi lo entiendo [Start] es una localizacion y pues el valor que se encuentre a donde apunte Start es el que se restara al acumulador.Asi lo entiendo yo tambien.
Un Saludo.
Escrito 16 diciembre 2008 - 07:30
Hola Fena, si asi lo entiendo [Start] es una localizacion y pues el valor que se encuentre a donde apunte Start es el que se restara al acumulador.Asi lo entiendo yo tambien.
Un Saludo.
Guardándose en el mismo Acumulador cierto ?... estoy tratando de desempolvar todas mis clases de Sistemas Digitales... Disculpen si las preguntas son un poco "sosas" son con puro afán de aprender...![]()
Escrito 16 diciembre 2008 - 07:35
Quiero postear aqui el codigo en cuestion para que este mas a mano:
function Elapsed: PChar; {$j+} // retorna el lapso entre Start hasta el momento de la //llamada en una cadena con formato de hora const Time: array [0..11] of Char = '00:00:00.00'; asm call GetTickCount // obtenemos el la cantidad de Ticks actual sub eax, [Start] // la restamos Start obteniendo el lapso en milisegundos xor edx, edx // las divisiones son realizadas con un entero de 64 bits (EAX:EDX) push ebx // guardamos el valor de EBX push 0Ah pop ecx // ECX := 10; uso push y pop para reducir la cantidad de opcode generada div ecx // dividimos el lapso de tiempo entre diez para usar centesimas en lugar //de milesimas; ésto por el formato de salida mov ecx, 183C3C64h // ECX sera rotado para los procesos de division; primero las centesimas (100), //luego los segundos (60), minutos (60) y horas (24)... al mismo tiempo cuando //se realicen estas operaciones la funcion retornará lea ebx, Time[12] // EBX := Result[12]; definimos y usamos como puntero a EBX el cual inicia apuntando // a las centesimas mas dos posiciones (pensado originalmente para optimizar con milesimas) @loop: push ecx // guardamos ECX pues modificaremos su valor temporalmente xor edx, edx // (EAX:EDX) movzx ecx, cl // solo usamos los primeros 8 bits (100, 60, 60, 24) div ecx // dividimos xchg edx, eax // EDX contiene el módulo (residuo) que es lo que nos interesa, por ello lo intercambiamos // con EAX para volver a realizar una division mov cl, 0Ah div cl // lo dividimos por 10, con lo cual obtenemos en AL y AH los valores or ax, '00' // los convertimos a ASCII sub ebx, 3 // restamos e puntero del buffer de retorno en 3 para continuar el mismo proceso con los segundos, //minutos y horas mov [ebx], ax // guardamos el resultado en ASCII de las divisiones xchg edx, eax // restauramos EAX que debe contener el resultado de la division original y no asi el residuo pop ecx // restauramos ECX para continuar con las otras divisiones shr ecx, 8 // y rotamos ECX para dividr respectivamente entre 60, 60 y 24 jnz @loop // terminamos al haber realizado las 4 divisiones (centesimas, segudos, minutos y horas) xchg eax, ebx // la funcion retornara el valor que apunta EBX (PChar) pop ebx // restauramos el valor original de EBX pues es un registro utilizado "internamente" por el lenguaje end;
Escrito 16 diciembre 2008 - 08:23
mov ecx, 183C3C64h // ECX sera rotado para los procesos de division;
primero las centesima (100) //luego los segundos (60), minutos (60) y horas (24)... al mismo tiempo cuando
Escrito 16 diciembre 2008 - 09:41
Un pequeño ejercicio:
procedure TForm1.Button1Click(Sender: TObject); var result: integer; begin asm Mov eax, 18h; // ponemos el valor 18 hex en el acumulador Mov result,eax; end; edit1.text:=inttostr(result); // aqui nos regresara el 24 decimal end;
Escrito 17 diciembre 2008 - 07:15
Escrito 17 diciembre 2008 - 07:20
Hola josé, me está interesando este asunto del ASM, ¿por casualidad existe una tabla de equivalencias de esos valores?.
Saludos.
Escrito 17 diciembre 2008 - 07:24
Escrito 17 diciembre 2008 - 09:00
Aqui tienes un buen documento para comenzar:
http://www.comms.sci...fAsm/APNDXD.PDF
Un Saludo.
Escrito 17 diciembre 2008 - 09:17
En primer lugar creo necesario aclarar que éste hilo ha comenzado por la necesidad de enseñar un código utilizado en éste juego.
Como segunda y ultima aclaración es bueno entender claramente que un opcode es el código binario generado a partir de instrucciones nemotécnicas (lenguaje de maquina en este caso), y casi siempre es un tema inherente al momento de aprender y desarrollar una aplicación escrita en lenguaje de maquina.
Al grano, vamos bien Jose; ahora nutramos un poco estas ideas (y otras); creo que lo primero es hablar acerca de la API GetTickCount, la cual retorna la cantidad de milisegundos transcurridos desde que el SO inicia. Sabiendo esto podemos usarla para obtener el tiempo transcurrido entre un momento y otro;
procedure TForm1.Button1Click(Sender: TObject); var Start: Cardinal; begin Start := GetTickCount; // operacion cronometrada... ShowMessage(IntToStr(GetTickCount - Start) + ' milisegundos transcurridos.'); end;
// ... var Start: Cardinal; Buffer: array [0..11] of Char = '00:00:00.00'; procedure TForm1.Button1Click(Sender: TObject); var Time, Value: Cardinal; begin Time := (GetTickCount - Start) div 10; // "convertimos" milesimas a centesimas // en cualquier conversion de base se debe utilizar divisiones y residuos Value := Time mod 100; // centesimas (lo que nos interesa es el residuo) Time := Time div 100; // eliminamos de Time dicho valor para la siguiente operacion Buffer[10] := Char((Value mod 10) or Ord('0')); // "mod 10" retornara el valor "derecho" de 99 Buffer[9] := Char((Value div 10) or Ord('0')); // "div "10" el valor "izquierdo" // en ambos casos le aumentamos el valor decimal de "0" para convertirlo a ASCII Value := Time mod 60; // segundos (pseudo "base 60"?) Time := Time div 60; Buffer[7] := Char((Value mod 10) or Ord('0')); Buffer[6] := Char((Value div 10) or Ord('0')); Value := Time mod 60; // minutos Time := Time div 60; Buffer[4] := Char((Value mod 10) or Ord('0')); Buffer[3] := Char((Value div 10) or Ord('0')); Value := Time mod 24; // horas Time := time div 24; Buffer[1] := Char((Value mod 10) or Ord('0')); Buffer[0] := Char((Value div 10) or Ord('0')); // podriamos seguir operando en "Time" para saber la cantidad de dias transcurridos Caption := Buffer; end; procedure TForm1.FormCreate(Sender: TObject); begin Start := GetTickCount; end;
Escrito 17 diciembre 2008 - 09:42
Escrito 17 diciembre 2008 - 10:33
Aqui tienes un buen documento para comenzar:
http://www.comms.sci...fAsm/APNDXD.PDF
Un Saludo.
Gracias José, viendo el PDF pues me he quedado igualito
Escrito 17 diciembre 2008 - 11:42
Escrito 17 diciembre 2008 - 03:38
procedure TForm1.Button1Click(Sender: TObject); var result: integer; begin asm Mov eax, 183C3C64h; movzx eax, al; // aqui nos quedamos con 'AL' solamente en el acumulador(64) Mov result, eax; end; edit1.text:=inttostr(result); // aqui nos muestra AL en decimal (100) end;