elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Estamos en la red social de Mastodon


  Mostrar Temas
Páginas: 1 2 [3]
21  Programación / Programación C/C++ / Código de una máquina virtual simple en: 6 Marzo 2013, 21:55 pm
Estoy haciendo un manual de la creación de una máquina virtual, no creo que tenga que decir que en C... por algo estamos en el foro: "Programación C/C++"  ::). A continuación pongo el código fuente totalmente creado por mí basandomes en diversa información:
Código
  1. /*
  2.  * Miky Gonzalez Virtual Machine - Segunda revisión
  3.  * Compilar con: gcc -o vm vm.c -O2
  4.  * Para más información y futuras versiones visita:
  5.  * http://mikygonzalez.16mb.com/
  6. */
  7.  
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10.  
  11. #define MAXIMOS_NODOS 100
  12.  
  13. typedef struct _nodo {
  14. int reg_pila;
  15. struct _nodo *siguiente_nodo;
  16. } nodo;
  17.  
  18. typedef nodo *__nodo;
  19. typedef nodo *__pila;
  20.  
  21. typedef struct _cpu {
  22. int reg[16];
  23. unsigned short int reg_temp[5];
  24. unsigned short int estado;
  25. unsigned int instruction_pointer;
  26. __pila pila_cpu;
  27. } cpu;
  28.  
  29. /*! FUNCIONES DE LA PILA */
  30. void push(__pila *pila, int num) {
  31. __nodo nodo_push;
  32.  
  33. nodo_push = (__nodo) malloc(sizeof(nodo));
  34. if(nodo_push != NULL) {
  35.     nodo_push->reg_pila = num;
  36.     nodo_push->siguiente_nodo = *pila;
  37.     *pila = nodo_push;
  38.    }
  39. }
  40.  
  41. int pop(__pila *pila) {
  42. __nodo nodo_pop;
  43. int valor_nodo_pop = 0;
  44.  
  45. nodo_pop = *pila;
  46. valor_nodo_pop = (*pila)->reg_pila;
  47. *pila = (*pila)->siguiente_nodo;
  48. free(nodo_pop);
  49.  
  50. return valor_nodo_pop;
  51. }
  52.  
  53. unsigned int contar_nodos(__nodo nodo_pila) {
  54. unsigned int valor_temporal = 0;
  55.  
  56. if(nodo_pila == NULL)
  57. return valor_temporal;
  58. while(nodo_pila != NULL) {
  59. nodo_pila = nodo_pila->siguiente_nodo;
  60. valor_temporal++;
  61. }
  62.  
  63. return valor_temporal;
  64. }
  65.  
  66. /*! FUNCIONES DEL CPU */
  67. void iniciar_datos(cpu* CPU) {
  68. unsigned short int bucle_i;
  69.  
  70. for(bucle_i = 0; bucle_i < 16; bucle_i++)
  71. CPU->reg[bucle_i] = 0;
  72.  
  73. CPU->estado = 1;
  74. CPU->instruction_pointer = 0;
  75. CPU->pila_cpu = NULL;
  76. }
  77.  
  78. void mostrar_datos(cpu* CPU) {
  79. unsigned short int bucle_i;
  80.  
  81. for(bucle_i = 0; bucle_i < 16; bucle_i++)
  82. printf("REG %d == %d\n", bucle_i, CPU->reg[bucle_i]);
  83.  
  84. printf("CPU ejecutandose: %s", CPU->estado ? "Si\n" : "No\n");
  85. printf("Instruction Pointer: %d\n", CPU->instruction_pointer);
  86. }
  87.  
  88. void preparar_cpu(cpu* CPU, unsigned short int instruccion) {
  89. CPU->reg_temp[0] = (instruccion & 0xF000) >> 12;
  90. CPU->reg_temp[1] = (instruccion & 0xF00) >> 8;
  91. CPU->reg_temp[2] = (instruccion & 0xF0) >> 4;
  92. CPU->reg_temp[3] = (instruccion & 0xF);
  93. CPU->reg_temp[4] = (instruccion & 0xFF);
  94. }
  95.  
  96. void ejecutar_cpu(unsigned int programa[], cpu* CPU) {
  97. int valor_temporal = 0;
  98.  
  99. while(CPU->estado) {
  100. preparar_cpu(CPU, programa[CPU->instruction_pointer]);
  101. switch(CPU->reg_temp[0]) {
  102. case 0: /*! halt */
  103. CPU->estado = 0;
  104. break;
  105. case 1: /*! setr */
  106. // Comprobar si los datos estan dentro de los registros accesibles
  107. if(0x0 > CPU->reg_temp[1] > 0xF) {
  108. printf("Error: setr espera un registro valido\n");
  109. CPU->estado = 0;
  110. break;
  111. }
  112. CPU->reg[CPU->reg_temp[1]] = CPU->reg_temp[4];
  113. break;
  114. case 2: /*! push */
  115. // Comprobar si los datos estan dentro de los registros accesibles
  116. if(0x0 > CPU->reg_temp[1] > 0xF) {
  117. printf("Error: push espera un registro valido\n");
  118. CPU->estado = 0;
  119. break;
  120. }
  121. // Comprobar elementos maximos de la pila
  122. if(contar_nodos(CPU->pila_cpu) == MAXIMOS_NODOS) {
  123. printf("Error: desbordamiento de pila. MAX: %d\n", MAXIMOS_NODOS);
  124. CPU->estado = 0;
  125. break;
  126. }
  127. push(&CPU->pila_cpu, CPU->reg[CPU->reg_temp[1]]);
  128. break;
  129. case 3: /*! pop */
  130. // Comprobar existe almenos un elemento en pila_cpu
  131. if(CPU->pila_cpu == NULL) {
  132. printf("Error: pop espera un elemento en pila\n");
  133. CPU->estado = 0;
  134. break;
  135. }
  136. pop(&CPU->pila_cpu);
  137. break;
  138. case 4: /*! move */
  139. // Comprobar existe almenos un elemento en pila_cpu
  140. if(CPU->pila_cpu == NULL) {
  141. printf("Error: move espera un elemento en pila\n");
  142. CPU->estado = 0;
  143. break;
  144. }
  145. // Comprobar si los datos estan dentro de los registros accesibles
  146. if(0x0 > CPU->reg_temp[1] > 0xF) {
  147. printf("Error: move espera un registro valido\n");
  148. CPU->estado = 0;
  149. break;
  150. }
  151. valor_temporal = CPU->reg[CPU->reg_temp[1]];
  152. CPU->reg[CPU->reg_temp[1]] = CPU->pila_cpu->reg_pila;
  153. CPU->pila_cpu->reg_pila = valor_temporal;
  154. break;
  155. default:
  156. printf("Instruccion %d no implementada...\n", CPU->reg_temp[0]);
  157. break;
  158. }
  159. valor_temporal = 0;
  160. CPU->instruction_pointer++;
  161. }
  162. }
  163.  
  164. /*! INICIO DE MG-VM */
  165. int main(int argc, char *argv[]) {
  166. cpu CPU;
  167. unsigned int programa[] = {
  168. 0x1010, // setr 0 10
  169. 0x2000, // push 0
  170. 0x4100, // move 1
  171. 0x2100, // push 1
  172. 0x3000, // pop
  173. 0x3000, // pop
  174. 0x0000  // halt
  175. };
  176.  
  177. iniciar_datos(&CPU);
  178. mostrar_datos(&CPU);
  179.  
  180. ejecutar_cpu(programa, &CPU);
  181. mostrar_datos(&CPU);
  182.  
  183. return 0;
  184. }

Si encuentran una manera mejor de hacer las cosas, o más optimizada, porfavor, puedes comentar que propones. Cualquier sugerencia o queja son bienvenidas.
La máquina virtual sólo cuenta con funciones de manejo de la pila y registros. No tiene funciones artiméticas, en la próxima versión entrarán las demás funciones aritméticas. En total tengo un máximo de 16 funciones.

Un saludo, espero que les agrade el código. Intenté escribirlo para que pudiera entenderlo bien, aún siendo principiante en programación.

Para obtener más información del tutorial ó próximas revisiones del código: http://mikygonzalez.16mb.com/
22  Programación / Programación C/C++ / [C]-[AYUDA] Encontrar una sección en ejecutable en: 18 Febrero 2013, 20:05 pm
Hola a todo el mundo!. Estoy programando... una cosilla... en C, pero tengo un problema; Explico:
Yo tengo un ejecutable, suponiendo con este codigo:
Código
  1. unsigned char string[255] = {0xef, 0xbe, 0xad, 0xde} // 0xdeadbeed
Y ahora tengo otro ejecutable con el siguiente codigo:
Código
  1. while (1) {
  2.      if (read(archivo_fd, (void *) &numero_magico, 4) <= 3) break;
  3.      if (numero_magico == 0xdeadbeef) goto ir_a_seccion;
  4.      lseek(archivo_fd, 3, SEEK_CUR);
  5.      printf("Numero magico (actual): %lx\n", numero_magico);
  6.  }

El problema está, antes de nada, el código de antes está en crear un archivo ejecutable y con otro ejecutable abrir el archivo y buscar el contenido de numero magico (0xdeadbeef) para sustituir de ahí en adelante por una cadena. El problema se encuentra en que no me encuentra el número mágico... alguien podría ayudar. Gracias
23  Programación / Programación C/C++ / Ayuda - Saber si se repiten caracteres en una misma cadena en: 4 Julio 2012, 13:43 pm
Buenas, haber, hacer si un caracter se repite en una cadena (ver cuantas veces sale) se hacer, pero como hacer por ejemplo, que compare todos los caracteres de una cadena y ver si alguno se repite. Me explico:
Como puedo hacer para que dada una cadena: char string[5] = "Hola"; aqui no se repite ningun caracter pero si digo: "Hoola", saber que se repite un caracter.
No el buscar si el caracter 'o' se repite en la cadena; Si no si algun caracter dentro de la cadena se repite dentro de la misma cadena. ¿?
24  Programación / Programación C/C++ / Ayuda - Ajustar tamaño array - variable en: 4 Julio 2012, 11:46 am
Buenas, tengo el siguiente codigo:
Código
  1. char caracteres[39] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'}, prueba[] = "HOLA MUNDO";
Como puedo hacer por ejemplo que al hacer:
Código
  1. strcpy(caracteres, prueba);
Se ajuste el tamaño de caracteres a 11 (caracteres[11]) para ahorrar la memoria de esas posiciones que ya no usare. Al hacer el strcpy me queda:
Código
  1. char caracteres[39] = {'H', 'O', 'L', 'A', ' ', 'M', 'U', 'N', 'D', 'O', '\n', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'}
Como puedo eliminar lo anterior y ajustar el valor de caracteres[39] a caracteres[11] (se incluye el final de cadena).
25  Programación / Programación C/C++ / Ayuda - Buscar una cadena en parametros de funcion en: 4 Julio 2012, 11:23 am
Hola, tengo un pequeño problema que no soluciono:
Tengo (por ejemplo) la siguiente funcion: funcion main(int argc, char **argv).
Y tengo por ejemplo: si (argv[1] == "argumento1"); se escribio un argumento.
Pero como puedo hacer para buscar por ejemplo si se ha contenido en la lista de argumentos el argumento -e por ejemplo para especificar algo, es decir podria hacer: prog.exe a -e; u otro ejemplo prog.exe -e a.
Es decir que sepa si se ha especificado el argumento buscandolo.. intente con strcmp pero nose como hacer para buscar en todos los posibles argumentos que haya puesto
26  Programación / Programación C/C++ / Ayuda - Generador de diccionarios en: 30 Junio 2012, 15:53 pm
Estoy haciendo un codigo que llevaba bien hasta que me estanque en esto:

Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. void uso(char *);
  5. int main(int argc, char **argv) {
  6. unsigned short int tmp[5] = {0, 0, 0, 0, 0};
  7. char caracteres[39] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
  8. 't', 'u', 'v', 'w', 'x', 'y', 'z'};
  9. if (argc > 4 || argc < 3) uso(argv[0]);
  10. if (argv[1] == NULL) { printf("ERR ARG:1: Se debe especificar nombre de archivo\n"); uso(argv[0]); }
  11. if (atoi(argv[2]) == 0) { printf("ERR ARG:2: Debe especificarse un numero (longitud de cadena)\n"); uso(argv[0]); }
  12. FILE *file;
  13.    file = fopen(argv[1], "w");
  14.    if (file == NULL) { printf("ERR ARG:1: Ocurrio un problema al abrir/crear el archivo\n"); uso(argv[0]); }
  15.    // GENERADOR DEL DICCIONARIO
  16. for (tmp[0] = 1; tmp[0] <= atoi(argv[2]); tmp[0]++) {
  17. for (tmp[4] = tmp[0]; tmp[4] >= 0; tmp[4]--) {
  18. for (tmp[1] = strlen(caracteres); tmp[1] >= 1; tmp[1]--) {
  19. printf("%c", caracteres[tmp[1]-1]);
  20. if (tmp[0] == 1) printf("\n");
  21. fputc(caracteres[tmp[1]-1], file);
  22. if (tmp[0] == 1) fputc('\n', file);
  23. }
  24. for (tmp[2] = tmp[4]; tmp[2] > 1; tmp[2]--) {
  25. for (tmp[1] = strlen(caracteres); tmp[1] >= 1; tmp[1]--) {
  26. printf("%c", caracteres[tmp[1]-1]);
  27. fputc(caracteres[tmp[1]-1], file);
  28. } printf("\n");
  29. }
  30. }
  31. }
  32.    fclose(file);
  33.    return 0;
  34. }
  35. void uso(char *name) {
  36. printf("Uso: %s archivo longitud [caracteres]\n", name); exit(0);
  37. }
  38.  

En la sección generador del diccionario solo hace bien la primera parte, me he liado mucho porque llevo como 40 minutos y no logro una solucion lo que quiero que haga:
z
..
a
zz
..
aa
..
zzz
..
aaa

Todas las combinaciones posibles dadas desde los parametros. El codigo creo que todo esta bien menos el algoritmo de generacion del diccionario. ¿Alguna solucion?. Gracias por leer.
27  Programación / Programación C/C++ / Ayuda - Funcion factorial de un numero en: 30 Junio 2012, 01:12 am
Hola, buenas... soy Mike Gonzalez. Estoy haciendo una calculadora por consola, mas bien el modulo de calcular y despues hare la GUI en VB6.
Tengo una funcion hecha que me permite calcular el factorial de un numero:

Código
  1. unsigned long int factorial(short int numero) {
  2.    int pred = 0;
  3.    unsigned long int tmp = numero;
  4.    for (pred = --numero; pred > 1; --pred)
  5.        tmp *= pred;
  6.    return tmp;
  7. }

Las declaraciones son unsigned porque se supone que asi gano mas memoria de calculo (en el almacenamiento de variables). Mi pregunta es que solo me permite calcular hasta el factorial de 25 (a partir de ahi da resultados negativos :S).
Alguna solucion de mejorar el codigo y/o permitirme calcular numeros mas elevados (las calculadoras normales llegan al 69).

Gracias de antemano.
Páginas: 1 2 [3]
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines