Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Mensajes - Miky Gonzalez

#51
Vale he utilizado el esquema de la función crear_cpu() de Khronos, queda algo como esto, por si puede ayudar a alguien:

unsigned int crear_cpu(cpu_t *cpu, unsigned char *memoria) {
if(!memoria || !cpu) return 0;

//memset(cpu_init->registro, 0, sizeof(cpu_init->registro) / sizeof(*cpu_init->registro));
unsigned int i = 0;
for(; i < 12; i++)
cpu->registro[i] = 0;
cpu->inst_pointer = 0;
cpu->memoria = memoria;

return 1;
}


Para crear la CPU llamo a la función de la siguiente manera:

/* Crear CPU e inicializar los datos */
cpu_t cpu;
if(!crear_cpu(&cpu, codigo)) {
printf("[MVM] Error al crear CPU...\n");
return 0;
}


Cuando tenga terminado el código es muy posible que lo postee. Tiene una buena base, así que supongo que lo continuaré y añadiré funciones de E/S, Sockets, entre otras cosas.

Gracias y saludos!
#52
Supongamos por un momento el siguiente código:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
//#include <inttypes.h>

/* MVM - Estructura de la MV */
typedef struct CPU {
unsigned int inst_pointer;
unsigned char *memoria;
} cpu_t;

cpu_t *crear_cpu(unsigned char *memoria) {
if(!memoria) return NULL;
cpu_t *cpu_init = malloc(sizeof(*cpu_init));
cpu_init->inst_pointer = 0;
       cpu_init->memoria = memoria;

return cpu_init;
}

void borrar_cpu(cpu_t *cpu) {
if(!cpu) return;
//void *datos = (void *)((uintptr_t)cpu);
//free(datos);
free(cpu);
}

int main(int argc, char *argv[]) {
/* Inicializar datos y comprobar argumentos */
if(argc < 2) {
printf("Uso: %s <archivo>\n", argv[0]);
return 0;
}
unsigned int codigo_volumen = 100;
/* Reservar el espacio necesario para almacenar
* el código en memoria. Si existe, copiarlo. */
unsigned char *codigo = (unsigned char *)malloc(codigo_volumen);
if(!fread(codigo, 1, codigo_volumen, ARCHIVO)) {
fclose(codigo_archivo);
return 0;
} else fclose(codigo_archivo);

cpu_t *cpu = crear_cpu(codigo);
if(!cpu) return 0;

borrar_cpu(cpu);
free(codigo);

return 0;
}


Faltan muchas parte del código, pero está lo esencial para mi cuestión. Explico un poco el funcionamiento:
Es una máquina virtual (¿dificil de saber?, no creo xD), en la que leo un archivo, calculo el tamaño, creo memoria dinamica para almacenar el contenido del archivo con malloc y fwrite respectivamente. Creo una variable con tipo estructura de la CPU de la MV, llamo a la funcion que me crea la CPU y le asigna el puntero. Despues libero la memoria del codigo (supuestamenta) y la de la CPU creada con la funcion crear_cpu, a través de la función borrar_cpu.
Creo que estoy utilizando mal, o los punteros, o el uso de free(). No se porqué, ni dónde, ni cómo hacerlo bien. El programa funciona correctamente, pero creo que hay fugas de memoria. ¿Podrían solventar mi problema?.
#53
Alguien tiene los sources o sabe de donde puedo conseguirlos?
#54
Voy a ir directo: tengo una función en C que me provoca un fallo de segmentación. He revisado y creo que los punteros están bien colocados y no devería de acceder a recursos de memoria no-accesibles.
void eliminar_espacios(char *contenido_linea) {
char *cadena_temporal = (char *)malloc(255);

while(*contenido_linea) {
if((*contenido_linea != 32) && (*contenido_linea != '\t')) {
contenido_linea++;
} else {
*cadena_temporal = *contenido_linea;
cadena_temporal++;
}
}

return (void)contenido_linea;
}


Elimina los espacios de una cadena.

Saludos!
#55
Soy consciente que pila es stack en ingles  ;D bueno, es una gran ignorancia, pero sinceramente, soy algo obsesivo con la palabra stack del inglés xD. Aunque si duelen muchos los ojos no me molestaría cambiar por stack :P
#56
Solucionaré los problemas, en cuanto a pedir el número de elementos en la matriz se solucionan los problemas, pero me gustaría hacer todo más automático. He estado pensando en leer el programa desde un archivo y reservar para programa[] tantos elementos como líneas tenga el archivo (por ejemplo).

Espero que no te importe que ponga la implementación en C++ en mi página.
#57
Solucionado el problema de la división; simplemente añadir en el código de la instrucción:

if(CPU->reg[CPU->reg_temp[2]] == 0) {
printf("Error: División por 0.\n");
CPU->estado = 0;
break;
}


Estoy pensando como solucionar el problema que calcular elementos del array. Yo probé con:

unsigned int array[] = {0x00, 0x01, 0x02, 0x03, 0x04};
num_elementos = sizeof(array) / 4;

pero no devuelve el tamaño total del array, siempre devuelve 4. Según la especificación de C si llamo a sizeof(xxxx) me devuelve el tamaño de la variable, pero no lo hace.

En cuanto a no colocar halt en el programa como fin de la ejecución por ello el código halt tiene como código OP: 0x00. Se supone que si se ejecuta una sección fuera del tamaño de variable finalizará.

La nueva versión está subida con la correción de la división por cero y la comprobación de errores en la instrucción goto eliminada, cuidado entonces. Intentaré hacer de una forma sencilla la cantidad de elementos de un array sin intervención del usuario.

Gracias por comentar y por buscar fallos. Saludos!
#58
Hace aproximadamente un par de semánas (estamos hablando de principio de marzo) publiqué el código fuente de una máquina virtual con un par de funciones.
Actualicé la máquina y tiene un juego de instrucciones como sigue:

halt    Detener la máquina virtual
setr    Establecer un valor inmediato en un registro
push    Almacena en la pila el valor de un registro
pop    Elimina el TOS (primer elemento de pila)
move    Intercambia los valores entre el TOS y un registro
sum    Suma el valor de un registro y otro, el valor se almacena en el primer registro
div    Divide el valor de un registro y otro, el valor se almacena en el primer registro
mod    Divide el valor de un registro y otro, el valor del resto de división se almacena en el primer registro
mult    Multiplica el valor de un registro y otro, el valor se almacena en el primer registro
not    Niega un elemento
xor    Operación OR condicional con dos registros. El valor se almacena en el primer registro
shl    Mueve los bits de un registro hacia la izquierda un numero de veces como marque el segundo registro.
shr    Mueve los bits de un registro hacia la derecha un numero de veces como marque el segundo registro.
ife    Si los dos registros especificados son iguales, ejecuta la siguiente accion. En caso contrario la salta.
goto    Establece el 'ip' al valor inmediato dado.

El código fuente puede obtenerse de aquí

Unos ejemplos tambien pueden obtener desde aquí (con los opcodes correspondientes)

Un saludo, espero que les sirve de alguna utilidad. Un ejemplo de su uso podría ser por ejemplo para utilizar en algoritmo de cifrado, es mucho más difícil saber de donde sale un dato si este se está ejecutando virtualmente.

Puede obtener más información en: artículo
#59
0xDani: Gran aporte, yo tan sólo quería mostrar el cometido de una manera sencilla, fácil y eficaz; dije que gran aporte?, si no lo dije, gran aporte. xD
#60
Haber, no sabía como poner esto hexactamente, así que pense en un nombre:

Hexadecimal Dumper And To C Convertor

Creo que no hace falta explicar mucho, es un dumpeador hexadecimal para convertir cualquier archivo a variable del tipo char en C. En otras palabras, convierte:

#include <stdio.h>

double factorial(short int numero) {
    int pred = 0;
    double tmp = numero;
    for (pred = --numero; pred > 1; --pred)
        tmp *= pred;
    return tmp;
}

int main(void) {
    double factor87 = factorial(87);
    printf("Factorial de 87: %.20lg", factor87);
    getchar();   
    return 0;
}


En esto:

char hexdump2c[] = {
0x23, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x20, 0x3c, 0x73, 0x74, 0x64, 0x69, 0x6f, 0x2e, 0x68, 0x3e,
0x0d, 0x0a, 0x0d, 0x0a, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x20, 0x66, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x69,
0x61, 0x6c, 0x28, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x20, 0x69, 0x6e, 0x74, 0x20, 0x6e, 0x75, 0x6d, 0x65, 0x72,
0x6f, 0x29, 0x20, 0x7b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x6e, 0x74, 0x20, 0x70, 0x72, 0x65, 0x64,
0x20, 0x3d, 0x20, 0x30, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x20,
0x74, 0x6d, 0x70, 0x20, 0x3d, 0x20, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x6f, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20,
0x20, 0x66, 0x6f, 0x72, 0x20, 0x28, 0x70, 0x72, 0x65, 0x64, 0x20, 0x3d, 0x20, 0x2d, 0x2d, 0x6e, 0x75, 0x6d,
0x65, 0x72, 0x6f, 0x3b, 0x20, 0x70, 0x72, 0x65, 0x64, 0x20, 0x3e, 0x20, 0x31, 0x3b, 0x20, 0x2d, 0x2d, 0x70,
0x72, 0x65, 0x64, 0x29, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x20,
0x2a, 0x3d, 0x20, 0x70, 0x72, 0x65, 0x64, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75,
0x72, 0x6e, 0x20, 0x74, 0x6d, 0x70, 0x3b, 0x0d, 0x0a, 0x7d, 0x0d, 0x0a, 0x0d, 0x0a, 0x69, 0x6e, 0x74, 0x20,
0x6d, 0x61, 0x69, 0x6e, 0x28, 0x76, 0x6f, 0x69, 0x64, 0x29, 0x20, 0x7b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20,
0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x20, 0x66, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x38, 0x37, 0x20, 0x3d, 0x20,
0x66, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x69, 0x61, 0x6c, 0x28, 0x38, 0x37, 0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20,
0x20, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x66, 0x28, 0x22, 0x46, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x69, 0x61,
0x6c, 0x20, 0x64, 0x65, 0x20, 0x38, 0x37, 0x3a, 0x20, 0x25, 0x2e, 0x32, 0x30, 0x6c, 0x67, 0x22, 0x2c, 0x20,
0x66, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x38, 0x37, 0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x67, 0x65,
0x74, 0x63, 0x68, 0x61, 0x72, 0x28, 0x29, 0x3b, 0x20, 0x20, 0x20, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72,
0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x30, 0x3b, 0x0d, 0x0a, 0x7d, 0x0d, 0x0a};


El código fuente del programa es: /* Simple dumpeador de archivos a hexadecimal y guardar en C
* http://mikygonzalez.16mb.com
*/

#include <stdio.h>

#define TAM_HEXCODE 18

/*! Función principal hexdump */
void hexdump(FILE *archivo_fd) {
unsigned short int bucle_i;
char caracter_actual = '\0';
fseek(archivo_fd, 0, SEEK_SET);

while(!feof(archivo_fd)) {
for(bucle_i = 0; bucle_i < TAM_HEXCODE; bucle_i++) {
caracter_actual = fgetc(archivo_fd);
if(caracter_actual == EOF)
return (void) 0;
printf("0x%.2x, ", caracter_actual);
}
printf("\n");
}
}

int main(int argc, char *argv[]) {
FILE *archivo_fd;

if(argc < 2)
return 1;
if(!(archivo_fd = fopen(argv[1], "rb")))
return 1;

printf("char hexdump2c[] = {\n");
hexdump(archivo_fd);
printf("\b\b};\n");

return 0;
}


También pueden encontrarse este y otros programas en: http://pastes.mikygonzalez.16mb.com/?ad2cea935c65385a#c0bI9LQ9BD6f8snTLpklw/LgzXRnOEs6lJHJWqbbb9c= o en mi pagina personal (en la firma).

Saludos