Página 1 de 3
¿"Sabe" REALMENTE un programa su PROPIA longitud?
Publicado: 16 Oct 2012, 10:29
por Hark0
Buenas!
En relación al hilo
"Aprendiendo a programar un Emulador (DCPU-16)" (
viewtopic.php?f=15&t=680)
Supongamos que en memoria tengo esto:
(Ubicado en la posición 0x0000 de la RAM, al inicio... lo que lee la CPU al arrancar vamos)0x8001,0x7801,0x000B,0x7C09,0x01FF,0x7901,0x8000,0x000B,0x85E2,0x000B,0x85C1,0x0000,0x0000,0x0000,0x0000,0x0000,...
El programa son 11 word's, luego sigue RAM vacía...
Ahora pongamos que quiero DESENSAMBLAR esto...
Empezaría en 0x0000 y seguiría descodificando instrucciones y tal... ¿hasta?
a) los 0x0000 ??? (entiendo que puede haber varios/muchos DAT con valor "0")
b) fin de RAM???
c) a elegir por el usuario?
d) se especifica al cargar?
Saludos.
(PD He abierto un nuevo hilo sobre este asunto, ya que aunque considero que es aplicable al emulador del hilo comentado... sirve también para TODO lo relacionado con la programación

)
Re: ¿"Sabe" REALMENTE un programa su PROPIA longitud?
Publicado: 16 Oct 2012, 11:44
por scooter
No tengo ni idea de como va ese emulador, pero te contesto de forma genérica para un microprocesador/microcontrolador
En los que conozco ni sabes ni puedes saber donde acaba el ejecutable, lo que pasa es que la última instrucción es un salto para que reinicie el bucle, es un bucle vacío o algo semejante para saber donde dejas la CPU, no se le deja suelta que haga lo que quiera según encuentra datos aleatorios en la RAM.
Eso si, es probable que alguna directiva o función del ensamblador o compilador te devuelva en que posición estás, por ejemplo se podría hacer algo así en ensamblador de un 8052 (es el que mas he machacado y se parece algo a todos los intel)
Código: Seleccionar todo
org 0000
mov a,#final-final/256 'Carga acumulador la parte baja de la dirección de la etiqueta
mov b,#final/256 'carga reg b la parte alta de la dirección de la etiqueta
lcall print 'llama a una hipotética función que imprima en un display el contenido de AB, osea mostraría cuanto ocupa este programa
sjmp ! 'Bucle vacío, se queda dando vueltas en si mismo para siempre
final: 'etiqueta del ensamblador, su valor es el de la primera dirección libre
Re: ¿"Sabe" REALMENTE un programa su PROPIA longitud?
Publicado: 16 Oct 2012, 12:33
por zup
Según sistemas y lenguajes, los programas pueden saber (o no) su propia longitud. Se me ocurre:
- En un ZX Spectrum (BASIC), creo que puedes rastrear línea a línea su longitud (leer línea y longitud, leer siguiente línea... así hasta que te encuentres que no hay más BASIC).
- En un ZX Spectrum (C/M) realmente no tienes manera de saberlo... puedes leer inicio, longitud y ejecución desde el cargador, pero habitualmente se cargaba un solo bloque con programa, gráficos y demás datos mezclados.
- En MS-DOS: Los ficheros .COM tienen en el PSP guardado su tamaño, puedes consultarlo desde RAM o (mejor) desensamblar directamente desde el disco duro. Los ficheros .EXE es algo más complejo, pero también puedes saber algo.
En otros sistemas, puede haber (o no) mecanismos para conocer la longitud. Ten en cuenta que muchos programas pueden cargar en un solo bloque código y datos, con lo cual saber qué es código y que son datos es esencial para obtener un desensamblado con sentido.
Ahora bien, tu quieres saber la longitud con el programa ya en memoria... realmente no hay mucho donde pescar. Tendrías que conocer exactamente donde inicia y seguir el flujo de programa para saber qué son instrucciones, qué datos y qué basura (salvo en aquellos sistemas que guardan la longitud en un sitio accesible). En tu caso ya conoces la dirección de inicio, pero hay programas en los que la primera dirección de ejecución no coincide con el inicio del bloque que cargas.
Re: ¿"Sabe" REALMENTE un programa su PROPIA longitud?
Publicado: 16 Oct 2012, 12:51
por mcleod_ideafix
Algunos desensambladores sofisticados, como el IDA Pro, hacen una simulación de la ejecución para saber qué es código y qué son datos, pero para eso necesitan saber un punto de entrada de ejecución. Por lo general no es posible saber dónde termina un programa y empieza "memoria libre" porque, por lo general, cualquier secuencia de bytes podría ser una instrucción.
Ahora bien, hay algunas heurísticas que se pueden usar, en algunos casos, para acotar con más o menos éxito la longitud de un programa:
- Por ejemplo, en el Z80, el código de la instrucción NOP es 00h, por lo que varias partes de un programa en RAM que no estén contiguas en memoria, seguramente estén separadas por trozos más o menos grande de memoria a 00h
- Si el código está guardado en una ROM, EPROM o similar, el grabador podría haber optimizado el tiempo de grabación grabando realmente sólo el código o los datos del programa, y dejando el resto de posiciones sin grabar. Estas posiciones estarían a FFh, por lo que te encontrarías eso, regiones de memoria a FFh separando las diferentes rutinas y los datos.
- Algunos compiladores usan un carácter de relleno particular cuando generan código. Por ejemplo, en la arquitectura x86 cuando se programa para Windows, un carácter de relleno bastante usado es CCh , que es el código de operación de la instrucción INT 3, que es la instrucción de "breakpoint". Se usa este valor en particular para, si llegado el caso de que un programa se "vuelva loco" y por temas de corrupción de pila y tal se ponga a ejecutar código donde no le corresponde, caiga en una región llena de CCh y salte el depurador del S.O. o las rutinas de Just-in-time debugging.
- Cuando el programa está residente en memoria RAM en un S.O. con protección de memoria, es posible acotar dónde está el código si se miran los permisos de las diferentes páginas que componen el mapa de memoria del proceso. Las páginas que albergan código suelen marcarse como de solo lectura y ejecución. Las de datos, como de lectura/escritura.
Supongo que este problema es en cierto modo equivalente al teorema de incompletitud de Gödel. A mi me recuerda a estos problemas de computación que en realidad no son computables (no puede escribirse un algoritmo que los resuelva).
En general, y para resumir: la longitud de un programa es (una cota superior de dicha longitud en realidad) la cantidad de bytes a los que puede acceder ese programa con el mapa de memoria inicial que se le ha asignado.
Re: ¿"Sabe" REALMENTE un programa su PROPIA longitud?
Publicado: 16 Oct 2012, 13:01
por Hark0
scooter escribió:No tengo ni idea de como va ese emulador, pero te contesto de forma genérica para un microprocesador/microcontrolador
En los que conozco ni sabes ni puedes saber donde acaba el ejecutable, lo que pasa es que la última instrucción es un salto para que reinicie el bucle, es un bucle vacío o algo semejante para saber donde dejas la CPU, no se le deja suelta que haga lo que quiera según encuentra datos aleatorios en la RAM.
Eso si, es probable que alguna directiva o función del ensamblador o compilador te devuelva en que posición estás, por ejemplo se podría hacer algo así en ensamblador de un 8052 (es el que mas he machacado y se parece algo a todos los intel)
Código: Seleccionar todo
org 0000
mov a,#final-final/256 'Carga acumulador la parte baja de la dirección de la etiqueta
mov b,#final/256 'carga reg b la parte alta de la dirección de la etiqueta
lcall print 'llama a una hipotética función que imprima en un display el contenido de AB, osea mostraría cuanto ocupa este programa
sjmp ! 'Bucle vacío, se queda dando vueltas en si mismo para siempre
final: 'etiqueta del ensamblador, su valor es el de la primera dirección libre
Cierto, como comentas, interesa que esto sea
valido para cualquier emulador antiguo (o futuro)...
He visto el ensamblador de bastantes ejemplos de la CPU comentada y todos los programas suelen terminar en un bucle tonto al final... para que, como bien comentas... el PC (registro) no siga recorriendo la RAM hasta que tropiece con "basura" o código que NO interesa ejecutar...

Re: ¿"Sabe" REALMENTE un programa su PROPIA longitud?
Publicado: 16 Oct 2012, 13:05
por Hark0
zup escribió:Ahora bien, tu quieres saber la longitud con el programa ya en memoria... realmente no hay mucho donde pescar. Tendrías que conocer exactamente donde inicia y seguir el flujo de programa para saber qué son instrucciones, qué datos y qué basura (salvo en aquellos sistemas que guardan la longitud en un sitio accesible). En tu caso ya conoces la dirección de inicio, pero hay programas en los que la primera dirección de ejecución no coincide con el inicio del bloque que cargas.
Exacto!
Como he comentado "puede darse" que tenga 1000 words de DAT con valor 0000, con lo cual NO correspondería a RAM vacía sinó a datos necesarios...
Quizás la opción sera "ejecutarlo" y ver hasta donde llega y los words que lee...
Re: ¿"Sabe" REALMENTE un programa su PROPIA longitud?
Publicado: 16 Oct 2012, 13:13
por Hark0
mcleod_ideafix escribió:Algunos desensambladores sofisticados, como el IDA Pro, hacen una simulación de la ejecución para saber qué es código y qué son datos, pero para eso necesitan saber un punto de entrada de ejecución. Por lo general no es posible saber dónde termina un programa y empieza "memoria libre" porque, por lo general, cualquier secuencia de bytes podría ser una instrucción.
Ahora bien, hay algunas heurísticas que se pueden usar, en algunos casos, para acotar con más o menos éxito la longitud de un programa:
- Por ejemplo, en el Z80, el código de la instrucción NOP es 00h, por lo que varias partes de un programa en RAM que no estén contiguas en memoria, seguramente estén separadas por trozos más o menos grande de memoria a 00h
- Si el código está guardado en una ROM, EPROM o similar, el grabador podría haber optimizado el tiempo de grabación grabando realmente sólo el código o los datos del programa, y dejando el resto de posiciones sin grabar. Estas posiciones estarían a FFh, por lo que te encontrarías eso, regiones de memoria a FFh separando las diferentes rutinas y los datos.
- Algunos compiladores usan un carácter de relleno particular cuando generan código. Por ejemplo, en la arquitectura x86 cuando se programa para Windows, un carácter de relleno bastante usado es CCh , que es el código de operación de la instrucción INT 3, que es la instrucción de "breakpoint". Se usa este valor en particular para, si llegado el caso de que un programa se "vuelva loco" y por temas de corrupción de pila y tal se ponga a ejecutar código donde no le corresponde, caiga en una región llena de CCh y salte el depurador del S.O. o las rutinas de Just-in-time debugging.
- Cuando el programa está residente en memoria RAM en un S.O. con protección de memoria, es posible acotar dónde está el código si se miran los permisos de las diferentes páginas que componen el mapa de memoria del proceso. Las páginas que albergan código suelen marcarse como de solo lectura y ejecución. Las de datos, como de lectura/escritura.
Supongo que este problema es en cierto modo equivalente al teorema de incompletitud de Gödel. A mi me recuerda a estos problemas de computación que en realidad no son computables (no puede escribirse un algoritmo que los resuelva).
En general, y para resumir: la longitud de un programa es (una cota superior de dicha longitud en realidad) la cantidad de bytes a los que puede acceder ese programa con el mapa de memoria inicial que se le ha asignado.
Muy interesante!!!!
Creo que voy a utilizar el
"método temporal chapucero" de saber la longitud de bytes, en función de la longitud fichero...
Si el fichero tiene 32 bytes de longitud, tengo 32 words... luego en la posicion 32 de la RAM ya no hay NADA relativo al programa.
RAM: 0-31 bytes que corresponden al programa... byte 32 en adelante "vacio".
Implementar un desensamblador que ejecute etc, de momento se me hace demasiado cuesta arriba...

Gracias por la info a todos!!!
Re: ¿"Sabe" REALMENTE un programa su PROPIA longitud?
Publicado: 16 Oct 2012, 13:33
por scooter
El 8052 es un poco raro porque no es arquitectura Von newman, es harvar (o como se escriban) y tiene cuatro mapas de memoria, así que el código raramente estará en una ram, siempre será rom.
En CM es fácil saberlo poniendo una etiqueta al final, pero eso lo sabe el propio programa como el ejemplo tonto que he puesto, que lo sepa otro programa es mas delicado.
Desensablar es delicado; pueden haber trozos de datos con la directiva DB por enmedio del ejecutable. Eso yo lo usaba mucho en una rutina para imprimir mensajes constantes, se llama a la rutina que saca de la pila el contador de programa y empieza a leer caracteres hasta que llega a un terminador y regresa allí.
En ensamblador si no se hacen cosas raras y peligrosas normalemente todo el código va correlativo y basta con saber el tamaño del archivo si es un archivo binario. Si el archivo es un .hex o similar cada línea puede estar en una dirección diferente y cada línea puede tener un tamaño diferente. A bulto sale 1/3 del tamaño del archivo menos las cabeceras pero no se sabe cuantas cabeceras hay, habría que abrir el archivo y ver cuantas líneas hay, pero pueden haber huecos.
Si el código lo genera un compilador del lenguaje que sea, depende de lo ordenado que sea.
Para mi PFC me vi exactamente en este dilema; un sistema embebido podía recibir hasta ocho programas de usuario, como la cosa era simple no había protección de memoria, así que el usuario tenía que decir donde poner su archivo, el problema es que el compilador de C SDCC lo pone a trozos no correlativos y no siempre se detectaba bien.
El sistema recibía archivos .hex por el puerto serie y los flasheaba en la rom sin salir de la aplicación, cosa un bastante arriesgada ya que se podía pisar a si misma, lo que hacía era guardar la dirección del primer y último byte flasheado y eso informárselo al usuario así este sabía que huecos quedaban libres, claro que si el último byte flasheado no es el de dirección mas alta porque no son correlativos los paquetes la cosa no va.
Re: ¿"Sabe" REALMENTE un programa su PROPIA longitud?
Publicado: 16 Oct 2012, 13:42
por Hark0
scooter escribió:El 8052 es un poco raro porque no es arquitectura Von newman, es harvar (o como se escriban) y tiene cuatro mapas de memoria, así que el código raramente estará en una ram, siempre será rom.
En CM es fácil saberlo poniendo una etiqueta al final, pero eso lo sabe el propio programa como el ejemplo tonto que he puesto, que lo sepa otro programa es mas delicado.
Desensablar es delicado; pueden haber trozos de datos con la directiva DB por enmedio del ejecutable, yo eso lo usaba mucho.
Si no se hacen cosas raras y peligrosas normalemente todo el código va correlativo y basta con saber el tamaño del archivo si es un archivo binario. Si el archivo es un .hex o similar cada línea puede estar en una dirección diferente y cada línea puede tener un tamaño diferente. A bulto sale 1/3 del tamaño del archivo menos las cabeceras pero no se sabe cuantas cabeceras hay, habría que abrir el archivo y ver cuantas líneas hay.
Si el código lo genera un compilador del lenguaje que sea, depende de lo ordenado que sea.
Para mi PFC me vi exactamente en este dilema; un sistema embebido podía recibir hasta ocho programas de usuario, como la cosa era simple no había protección de memoria, así que el usuario tenía que decir donde poner su archivo, el problema es que el compilador de C SDCC lo pone a trozos no correlativos y no siempre se detectaba bien.
El sistema recibía archivos .hex por el puerto serie y los flasheaba en la rom sin salir de la aplicación, cosa un bastante arriesgada ya que se podía pisar a si misma, lo que hacía era guardar la dirección del primer y último byte flasheado y eso informárselo al usuario así este sabía que huecos quedaban libres, claro que si el último byte flasheado no es el de dirección mas alta porque no son correlativos los paquetes la cosa no va.
Jur...
¿Aqui no para uno de aprender nunca?

Re: ¿"Sabe" REALMENTE un programa su PROPIA longitud?
Publicado: 16 Oct 2012, 14:33
por Lex Sparrow
¿Sabe una persona cuánto tiempo va a vivir cuando nace?
Es curioso que la analogía sea aplicable en ambos casos.
