error en tiempo de ejecucion en programa c++

Iniciado por tca153, 8 Agosto 2021, 01:37 AM

0 Miembros y 1 Visitante están viendo este tema.

tca153

hola, tengo este ligero problema con una clase que hize, en esta clase tengo un puntero apuntado a la zona de video en modo texto (0xB8000000h) pero cuando trato de leer o escribir en esa direccion me da un error en tiempo de ejecucion (SEGMENTATION FAULT) y hay unos numeros antes que siempre cambian, que sera lo que pasa, yo probe esto en windows y siempre andubo bien, pero aca falla.
Para mas datos estoy usando binicpup 64 bits y el compilador es codelite, y aca esta la clase

#ifndef PANTALLA_H
   #define PANTALLA_H
   #include <iostream>
   
   class PANTALLA
   {
      private:
         int X,Y;
         unsigned char *scr;

      public:
      
         // Constructor
      
         PANTALLA()
         {
            scr=(unsigned char *)0xb8000000;
            X=Y=0;   
            clear();
         }
      
         void clear(void)
         {
            for(int i=1;i<2000;i+=2)
               *(scr+i)=0;      // punto en donde falla sin esto corre bien         
         }
   };

#endif // PANTALLA_H

cualquier ayuda sera muy apreciada, gracias

BloodSharp

#1
Cita de: tca153 en  8 Agosto 2021, 01:37 AMhola, tengo este ligero problema con una clase que hize, en esta clase tengo un puntero apuntado a la zona de video en modo texto (0xB8000000h)
¿Eso no era explícitamente hecho para DOS? cada sistema operativo debería de tener su manera apropiada de limpiar la pantalla debido a como manejan la memoria de cada dispositivo...

Cita de: tca153 en  8 Agosto 2021, 01:37 AMPara mas datos estoy usando binicpup 64 bits y el compilador es codelite, y aca esta la clase
Perdon por la ignorancia pero ¿que es binicpup? ¿Es BionicPup de PuppyLinux?

Si es una distro moderna de Linux podés hacer lo siguiente en la terminal:
Código (bash) [Seleccionar]
clear | hexdump -C
Luego te va a salir una secuencia de bytes, en mi caso es:
00000000  1b 5b 48 1b 5b 32 4a 1b  5b 33 4a                 |.[H.[2J.[3J|
0000000b

Al cuál se lo creo un programa en C o C++ da igual y le agrego un cero al final por las dudas:
Código (cpp) [Seleccionar]
#include <iostream>

int main()
{
    unsigned char bfClearScreen[]=
    {0x1b,0x5b,0x48,0x1b,0x5b,0x32,0x4a,0x1b,0x5b,0x33,0x4a,0x00};

    std::cout << bfClearScreen;
    return 0;
}


Y eso al menos a mí me funcionó perfectamente.

Enlace de referencia

GIF de demonstración:



B#



tca153

hola y muchísimas gracias por contestar, primero si la distro que uso es bionicpup 8.0 64bits, es el penúltimo puppy linux y hasta agora el ultimo con la opción de instalar en disco, la versión 9.5 solo viene con instalación frugal, y segundo, si se que puedo utilizar cout para dibujar y borrar, pero la idea es hacer un juego en modo texto que pueda después,  y con obvios retoques, a modo gráfico tal vez algún modo vesa, si no puedo hacerlo en modo texto, ya me puedo ir olvidando de hacerlo en modo gráfico donde voy a tener mas problemas, ojo se que puedo hacerlo usando qt designer o algún otro parecido pero me gusta programar para consola, el otro tema seria la velocidad y las prestaciones, no solo es mas rápido escribir en la pantalla usando un puntero que usando cout, también así puedo escribir un byte único en donde yo quiera dentro de la pantalla sino que también puedo controlar los atributos de cada byte en forma independiente a los demás bytes cosa que es mucho mas difícil con los métodos de la clase std

RayR

Como te dijo BloodSharp , eso es para el viejo DOS. No sirve para sistemas operativos modernos, por muchas razones. Que te funcionara en Windows se explica porque las versiones de 32 bits incluyen (o por lo menos así era antes) una máquina virtual de DOS para los programas de 16 bits, por lo que si el ejecutable fue generado con un compilador de 16 bits, y lo abres en esas versiones de Windows, va a funcionar, aunque de forma emulada, no nativa. Si de todas formas te interesa programar de esa manera por curiosidad, puedes instalar el emulador DOSBox, que tiene versiones para Windows y Linux, pero lo mejor es que simplemente uses funciones específicas del SO.

tca153

gracias para empezar soy nuevo en linux, a que funciones especificas te referis, y por otra parte, estamos de acuerdo que esa zona de memoria igual que la 0xA0000000, siguen existiendo?, si es asi no hay ninguna manera de romper esa barrera sin dañar al SO?

BloodSharp

Cita de: tca153 en  8 Agosto 2021, 14:11 PMpero la idea es hacer un juego en modo texto que pueda después,  y con obvios retoques, a modo gráfico tal vez algún modo vesa (...) no solo es mas rápido escribir en la pantalla usando un puntero que usando cout, también así puedo escribir un byte único en donde yo quiera dentro de la pantalla sino que también puedo controlar los atributos de cada byte en forma independiente a los demás bytes cosa que es mucho mas difícil con los métodos de la clase std

En GNU/Linux y supongo que varios Unixes existe la librería ncurses la cuál te permite calcular el tamaño de la terminal, escribir y supongo que también se puede leer al igual que borrar casillas:

Página de manual de ncurses

Por si te interesa hace mucho porté un mini juego FPS de Windows a Linux utilizando ncurses

[Aporte] Mini juego laberinto estilo FPS en terminal de Linux


B#



RayR

Cita de: tca153 en  8 Agosto 2021, 16:29 PM
gracias para empezar soy nuevo en linux, a que funciones especificas te referis, y por otra parte, estamos de acuerdo que esa zona de memoria igual que la 0xA0000000, siguen existiendo?, si es asi no hay ninguna manera de romper esa barrera sin dañar al SO?

Esas direcciones en sí no tienen nada de especial, es simplemente que bajo DOS, ahí se mapeaba la VRAM. Escribir en esas direcciones para modificar los pixeles o caracteres sólo tiene sentido bajo DOS o algún SO compatible, y con la tarjeta de video corriendo en modo EGA, VGA, etc. De todas formas los sistemas modernos usan memoria virtual, por lo que la dirección 0xb8000000 que ve tu programa no se corresponde con la dirección física 0xb8000000 en la RAM. Además, en general no permiten acceder directamente al hardware a los programas normales.

TL;DR: no se puede de esa manera. BloodSharp ya te dio algunas opciones con las que lo podrías hacer.

tca153

te agradezco la paciencia bloodsharp, tendre que cambiar de planes, una cosa mas, sabras como configurar code blocks para usar ncurses, logro que me detecte la ncurses.h pero no compila

BloodSharp

Cita de: tca153 en  9 Agosto 2021, 14:50 PMte agradezco la paciencia bloodsharp, tendre que cambiar de planes, una cosa mas, sabras como configurar code blocks para usar ncurses, logro que me detecte la ncurses.h pero no compila

Esta imagen la tomé prestada de stackoverflow, por lo que tenés que cambiar gdi32 por ncurses




B#



tca153

muchisimas gracias a los 2, RayR muchas gracias, y para BloodSharp pocas veces en foros vi gente como vos mas interesada en compartir lo que sabe que en criticar por no saber, a los dos un fuerte abrazo, y ahora a programar