2009-05-15 19 views
7

Tengo un código antiguo escrito en C para 16 bits usando Borland C++ que alterna entre varias pilas, usando longjmps. Crea una nueva pila haciendo un malloc, y luego configura los registros SS y SP para el segmento y desplazamiento, resp., De la dirección del área malloc'd, usando Assembler en línea. Me gustaría convertirlo a Win32, y parece que las dos instrucciones deberían ser reemplazadas por una sola configurando el ESP. Las dos instrucciones estaban rodeadas por un par de CLI/STI, pero en Win32 estas dan "instrucciones privilegiadas", así que las he cortado por ahora. Soy muy inocente en lo que respecta a Windows, así que, ¡estaba bastante sorprendido de que mi primer caso de prueba funcionara! Entonces, mi pregunta más bien vaga es preguntarles a los expertos si lo que estoy haciendo es a) demasiado peligroso para continuar, o b) funcionará si agrego algún código, tomo ciertas precauciones, etc. Si es este último, ¿qué debería agregarse y dónde puedo obtener información al respecto? ¿Debo preocuparme por otros registros, como SS, EBX, etc.? Estoy usando no optimización ... Gracias por cualquier consejo que la gente pueda darme.Pilas de conmutación en C++

+1

¡Guau, esa es una pregunta muy interesante! No soy exactamente un profesional en C++ de 16 bits, así que me pregunto por qué cambias las pilas en absoluto? –

+1

Dado que es un código antiguo de 16 bits, supongo que es una especie de implementación de fibra casera. Conozco un par de videojuegos de consola que hicieron algo como esto porque los hilos ofrecidos por el sistema eran muy pesados. – Charlie

+0

Sí, como señalaron varias de las excelentes respuestas, fue (fue) una implementación de fibra casera: mi primera implementación de la Programación basada en flujo en una PC. La versión de 16 bits se usó realmente para el trabajo de producción en una gran empresa de EE. UU. No me di cuenta de que Win32 tiene una implementación de fibras. Leeré el artículo citado por Greg Hewgill. ¡Gracias a todos ustedes! –

Respuesta

9

La eliminación de CLI/STI sigue funcionando debido a las diferencias en el entorno operativo.

En DOS de 16 bits, podría producirse una interrupción y esta interrupción se estaría ejecutando inicialmente en la misma pila. Si te interrumpieron en el medio de la operación, la interrupción podría bloquearse porque solo actualizaste ss y no sp.

En Windows y en cualquier otro entorno moderno, cada subproceso de modo de usuario obtiene su propia pila. Si su hilo se interrumpe por cualquier motivo, su pila y contexto se conservan de forma segura; no tiene que preocuparse de que se ejecute algo más en su hilo y su pila. cli/sti en este caso estaría protegiendo contra algo que ya está protegido por el sistema operativo.

Como mencionó Greg, la manera segura y compatible de intercambiar pilas como esta en Windows es CreateFiber/SwitchToFiber. Esto tiene el efecto secundario de cambiar todo tu contexto, por lo que no es como cambiar la pila.

Esto realmente plantea la pregunta de lo que quiere hacer. Muchas veces, el cambio de pilas es por espacio de pila limitado, que fue de 64k en DOS de 16 bits. En Windows, tiene una pila de 1 MB y puede asignar aún más. ¿Por qué estás tratando de cambiar pilas?

+0

Esta fue mi primera implementación de programación basada en flujo en una PC. No me di cuenta de que Win32 tiene una implementación de fibras, pero puede ser un gran problema convertir mi código en Fibras; sin embargo, leeré el artículo citado por Greg Hewgill. ¡Gracias a todos ustedes! –

5

La forma más segura de hacerlo es portar el código a las estructuras oficiales de multiprogramación de Win32, como hilos o fibras. Fibers proporciona un paradigma de múltiples pilas muy liviano que suena como si fuera adecuado para su aplicación.

El artículo Why does Win32 even have fibers? es una lectura interesante también.

+0

Una de las publicaciones en ese artículo dice "cambiarían la base de la pila, pero no actualizarían el límite de la pila. O no cambiarían la lista de manejadores de excepciones u olvidaría intercambiar el estado de la FP". Asumiendo que las fibras se ocupen de esas cosas por mí, ¿puedo hacer longjmps entre fibras? Si quería cuidarlos yo mismo, ¿qué tan complejos son, y dónde puedo encontrarlos? Gracias. –

+1

Ya he vinculado a la documentación de MSDN sobre fibras en mi respuesta. Aquí hay una referencia de función completa, que debería responder la mayoría de sus preguntas. Tenga en cuenta que no creo que deba intentar "longjmp entre fibras", sino que utilice las funciones oficiales como SwitchToFiber. –

+0

Gracias, Greg. La documentación parecía un poco desagradable, pero comenzaré a investigar. –

0

He hecho esto en modo de usuario, y parece que no tiene problemas. No necesita cli/sti, estas instrucciones simplemente evitan las interrupciones en ese punto del código, lo cual no debería ser necesario a partir de la información limitada que nos ha indicado.

0

Eche un vistazo a Mtasker por Bert Hubert. Hace una simple multitarea cooperativa, podría ser fácil para usted usar esto para portar su código.

0

No olvide que las pilas de saltos absorberán cualquier argumento o variable residente de la pila.

Cuestiones relacionadas