|
Mostrar Mensajes
|
Páginas: 1 2 3 4 [5] 6 7 8 9
|
42
|
Programación / Programación C/C++ / [Ayuda] Conversiones *char - int
|
en: 17 Septiembre 2013, 17:43 pm
|
Supongamos que yo tengo la siguiente matriz: char codigo[] = {0x00, 0xFF, 0x01, 0x03, 0x01, 0xFF, 0xFF, 0x00};
Con esta matriz se podrian hacer muchas cosas, desde interpretarla, hasta leer numeros. Mi pregunta: En la posición 5 (recordar que empieza desde 0) y en la 6 hay 0xFF. Perfectamente podria poner en numero entero como 256, 256. Pero mi cuestion es: ¿Cómo puedo leer esos dos 0xFF, para que me queden como un 0xFFFF (tamaño de short int). Para que me entiendan, si hubiera: 0x4F, 0x33; quedaria: 0x4F33. Se me ocurrieron varias opciones como: (0x4F << 2) & 0x33, pero ningun me funciona. ¿Podrían ayudarme?
|
|
|
43
|
Programación / Programación C/C++ / [Aporte-C][Avance] Instrucciones de la VM con ejemplo
|
en: 8 Septiembre 2013, 19:26 pm
|
Llevo ya desarroyando una máquina virtual largo tiempo, pero no tengo mucho tiempo, estoy con otros proyectos más importantes. Las funciones actuales (no creo que implemente alguna función más, sólo características y ampliaciones):
0x00 | halt | detiene el cpu | 0x01 | lit | cargar en acumulador un valor inmediato | 0x02 | load | cargar en acumulador valor de un registro | 0x03 | store | almacenar valor acumulador en un registro | 0x04 | inc | incrementar por 1 el acumulador | 0x05 | dec | decrementar por 1 el acumulador | 0x06 | pushl | poner en pila un valor inmediato | 0x07 | pushr | poner en pila valor de un registro | 0x08 | pop | eliminar 'cima de pila' (tos) | 0x09 | loadt | almacenar valor retorno de pop en acumulador | 0x0A | cmpl | comparar acumulador con valor inmediado. establece flag | 0x0B | cmpr | comparar acumulador con valor registro. establece flag | 0x0C | jmp | saltar a direccion de codigo (inicio == 0x00) | 0x0D | jmpl | saltar a direccion de codigo si flag == 1 ( < ) | 0x0E | jmpe | saltar a direccion de codigo si flag == 2 ( = ) | 0x0F | jmpg | saltar a direccion de codigo si flag == 3 ( > ) |
No es un juego de instrucciones completo ni facil de usar, pero teoricamente cualquier otra operación se puede hacer con esas instrucciones, de echo, hice una operación de multiplicar dos números (30 * 3): #======================================== # CALCULAR MULTIPLICACION DE DOS NUMEROS #======================================== # Utilizando tres registros se # pueden hacer funciones de multiplicación # de números. #======================================== # Inicialización de los datos lit 10 # ac: 10 store r0 # r0: 10 lit 3 # ac: 3 store r1 # r1: 3 lit 0 # ac: 0 # Bucles load r1 # ac: r1 dec # ac: ac-- store r1 # r1: ac cmpl 0 # comparar ac & 0 jmpe 23 # ac == 0 --> jmp 23 lit 10 # ac: 10 store r0 # r0: 10 load r2 # ac: r2 inc # ac: ac++ store r2 # r2: ac load r0 # ac: r0 dec # ac: ac-- store r0 # r0: ac lit 0 # ac: 0 cmpr r0 # comparar ac & r0 jmpl 13 # ac < r0 --> jmp 13 jmp 6 # jmp 6 lit 0 # ac: 0 store r1 # r1: 0 halt # stop
A la hora de ser compilado para la máquina virtual, queda una matriz como: char codigo[] = { 0x01, 0x0A, 0x03, 0x00, 0x01,0x03, 0x03, 0x01, 0x01, 0x00, 0x02, 0x01, 0x05, 0x03, 0x01, 0x0A, 0x00, 0x0D, 0x29, 0x01, 0x0A, 0x03, 0x00, 0x02, 0x02, 0x04, 0x03, 0x02, 0x02, 0x00, 0x05, 0x03, 0x00, 0x01, 0x00, 0x0B, 0x00, 0x0D, 23, 0x0C, 10, 0x01, 0x00, 0x03, 0x01, 0x00};
Cuya alternativa en código C: int num1, num2 = 3; int mult = 0; for (; num2 > 0; num2--) { for(num1 = 10; num1 > 0; num1--) { mult++; } }
Pueden si quieres crear sus propios algoritmos y postearlos en este mensaje, me ayudaría mucho, estoy intentando implementar "funciones externas", un archivo que incluya funciones para simplificar el trabajo. Esto es una multiplicación simple, seguramente se puede hacer optimizable y/o más corta, cualquier código que quieran crear utilizando esas funciones me ayudaria para probar la máquina virtual. En aproximadamente 2 semanas espero publicar el código fuente completo... no me gusta sacar 100 versiones para una aplicacion! Saludos
|
|
|
44
|
Programación / Programación C/C++ / Re: [Ejercicio] Sin usar tipo float
|
en: 8 Septiembre 2013, 16:00 pm
|
Entiendo lo que quieren decir, gracias por comentar.
Anotando, el ejercicio es puesto para C, no soy amigo de C++. Y la idea esque el que quiera lo utilice si no tiene nada que hacer e incluso podria sacar una libreria propia de numeros reales de tamaño ilimitado (aka GMP).
Saludos
|
|
|
45
|
Programación / Programación C/C++ / [Ejercicio] Sin usar tipo float
|
en: 7 Septiembre 2013, 16:13 pm
|
Supongamos por un momento que debes hacer un programa que calcule, lo más exactamente posible, una media, o cálculos, que de seguro, tendrán decimales. Sólo hay una pega, no puedes usar el tipo float bajo ningún concepto. Lo mejor para este ejercicio sería crear un archivo de cabezera que incluya estructura para crear tu propio tipo float basandote en tipos enteros. Hacer eso es muy facil: typedef struct _real { int entero; unsigned long int decimal; } real_t;
Pero se deben crear tambien unas funciones que nos permita actuar con sencillez, como si de un tipo entero se tratase. Puedes empezar por estas funciones: real_t declarar_real(int entero, unsigned long int decimal) { real_t real; real.entero = entero; real.decimal = decimal; return real; } #define mostrar_real(a) printf("%d.%u", a.entero, a.decimal)
Lo que se pide en este ejercicio, para quienes quieran hacerlo para practicar sus conocimientos: Crear funciones de suma y resta de numeros tipo real, al igual que funciones de multiplicación y división. Si has echo lo anterior, prueba a modificar la estructura para que admita un número ilimitado de decimales (podrías hacerlo con una matriz dinámica).
|
|
|
46
|
Programación / Programación C/C++ / Re: [Opinion] Programando un lenguaje ensamblador semicompilado en C
|
en: 8 Agosto 2013, 16:26 pm
|
Gracias por comentar, leo todos los comentarios, aunque no siempre tengo tiempo para contestar. Leí todas las indicaciones y miré algunas máquinas virtual y frameworkd como lo son la JVM y la plataforma .NET. Algunas notaciones que pusistes me parecieron útiles, que no pensé demasiado en ellas. El analizador léxico-sintáctico lo estoy programando en este instante, pero el tema de los espacios, saltos de línea no es de momento inconveniente, funcionando de la siguiente forma y manera: 1. Leo el archivo y paso su contenido (exceptuando comentarios ' y '= hasta =') a un buffer dinámico (así me aseguro). 2. Hago un parser inicial eliminando datos "obvios/inutiles", como son espacios entre funciones, declaraciones; respetando las reglas de conducta que se deben seguir. En esta etapa se deben precalcular resultados (por ejemplo add r1 (23+2+32+3+2),(23+2+3+2)). 3. Hago un segundo parser comprobando sintexis y pasando a opcode y guardando estos en un archivo. Por supuesto, está echo para que el fichero contenga toda la información y ocupe lo menos posible.
Es la forma más rápida, eficiente y limpia que encontré de programar el conversor a opcodes.
Para aclararte, no esta en mis pensamientos incluir una función para copiar el valor de un registro en otro. Como especifico, puedes hacer una subrutina a forma de libreria libre. Por supuesto, que todas las librerias que se usen a modo de API, serán libres, y espero que la máquina virtual tambien. De momento no puedo poner el código, pero si quieres echarle un vistazo, contactame.
He decidido modificar el proyecto para seguir otro camino, pero sin salirse del camino de aprender y hacer aprender. Pongo los cambios y las nuevas especificaciones: La utilización de registros, tratándose de ellos, ahora se utilizará (como antes) precedida del carácter 'r'. La utilización de valores numéricos se especificará con '#'. Por ejemplo: add r2 r5 #50 ' guarda en el registro 2 la suma del registro 5 más 50 (decimal)
Implementaré funciones simples (que pueden dar lugar a funciones complejas) de utilización de posiciones de memoria dentro de la máquina virtual (punteros para acceder a ellas). Para especificar una posición de memoria debe utilizarse el carácter @: @1000 ' posicion de memoria 1000 (decimal).
Una especificación que me faltó de dar en el post principal es la generación de los opcodes, como es por ejemplo: una función sin parámetros utiliza un byte de tamaño: 0x00. Si utiliza parámetros, dependiendo de estos: 0x00 0x00 0x00 (funcion param1 param2).
Función 'halt' - Tendra el opcode 0x00. Obviamente, esto detendrá la máquina virtual cualquier punto en que esta se encuentre. Tiene como opcode 0x00 porque supongamos que hay un error de programación y se empieza a leer fuera de memoria, la mayor parte de esta esta llena de ceros.
La idea que tuve es en hacer que los elementos de la pila tengan dirección de memoria (virtual en la máquina virtual), al ejemplo del elemento 1 (el último añadido) tendría la última dirección de memoria posible. Esto es así porque la pila se llena desde abajo.
Saludos, Miky Gonzalez
|
|
|
47
|
Programación / Programación C/C++ / [Opinion] Programando un lenguaje ensamblador semicompilado en C
|
en: 7 Agosto 2013, 22:15 pm
|
Me gustaría que me diesen alguna opinión acerca de las implementaciones actuales y en el apartado 'para hacer' las ideas que tengo. La máquina virtual está programada y es rápida. Usa memoria dinámica para el uso de registros y la pila. Pronto intentaré implementar para el uso de API y añadir funcionalidades propias sin modificar código interno.
Expecificaciones del lenguaje: Se trata de un microlenguaje de programación ensamblador orientado al uso de pila, registros y operaciones aritméticas. Esta diseñado con el mero propósito de aprender.
Dispone de 8 registros (r0-r7)(tipo entero), elegidos así porque me parece un número de registros adecuado. No admite cadenas de caracteres ni números reales. Es un lenguaje semicompilado, es decir, sus intrucciones son transmitidas a opcodes que son emulados por una máquina virtual (actualmente, la máquina virtual ya está en una buena fase de desarrollo).
Algunas especificaciones técnicas del lenguaje: · Debe respetarse el orden de parámetros · Los registros son numerados desde 0 a 7, indicando que es un registro con la letra 'r' precediendo al número. · Para definir el inicio del programa debera utilizarse la etiqueta %main% precedida de las intrucciones. · Para definir el fin del programa debera utilizarse la etiqueta %end main% · Para definir una funcion común (no implementado) deberá utilizarse la etiqueta %nombredefuncion,parametro1,param...% finalizando esta con %end nombredefuncion% · Pueden incluirse comentarios en el código con ' y '= ='. · Cada línea tendrá como máximo una función · Pueden definirse 'cotas' de código para hacer el código más pequeño, compartiendo biblioteca que pueden ser incluidas en el código con %include archivo.mvm%. Se dispondrá de version estándar de algunas implementaciones para agilizar el uso y ampliar las funciones con el uso de API.
Función 'setr' - Establece el valor a un registro: setr [r0-r7] num1 ' Uso normal
Función 'add' - Función con la capacidad de sumar 2 enteros y guardar la operación en el registro indicado: add [r0-r7] num1,num2 ' Uso normal Función 'addr' - Suma 2 enteros, uno de ellos dado por el valor de un registro. Con las funciones add y addr pueden hacerse todas las operaciones de suma desde sumar dos registros hasta sumar registro con datos de la pila: addr [r0-r7] rX,rX ' Uso normal Función 'neg' - Niega el valor de un registro dado: neg [r0-r7] ' Uso normal El equivalente a la función 'sub' se puede utilizar conjuntamente con 'addr' y 'neg': '= Queremos restar r1 - r0 y guardar valor en r3 =' neg r0 addr r3 r1 r0 Función 'mult' - Multiplica 2 enteros y guarda la operación en el registro dado: mult [r0-r7] num1,num2 ' Uso normal Función 'multr' - Multiplica el valor de 2 registros y guarda la operación en el registro dado: multr [r0-r7] rX,rX ' Uso normal Función 'push' - Pone el valor de un registro en pila: push [r0-r7] ' Uso normal Función 'pop' - Elimina el tos: pop ' Uso normal
Función 'inrp' - Intercambia el valor de un registro y del tos: inrp [r0-r7] ' Uso normal
El equivalente a 'inrr' (intercambiar dos registros, mov), puede hacerse con funciones ya descritas: '= Queremos intercambiar r0 y r1. Vamos a suponer que todos los registros tienen valores que deben ser guardados. =' push r0 inrp r1 inrp r0 pop
Otra utilidad que tiene las funciones anteriores, no se necesita de función 'clonr' (clonar valor de un registro en otro), ya que, esta podria hacerse de muchas otras maneras con inrp o addr.
Función 'cmp' - Comparar si el valor de un registro y un valor proporcionado son iguales, mayor, menor (con respecto al registro): cmp [r0-r7] num1 ' Uso normal
Función 'cmpr' - Comparar si el valor de dos registros son iguales, mayor, o menor (con respecto al primer registro): cmpr [r0-r7] [r0-r7] ' Uso normal
Para hacer: Cambiar la forma de analizar las funciones, para evitar usar funciones clonadas para operar con registros (add, addr, mult, multr...); Así, se podrá operar con los registros de una forma más fácil y comoda. Añadir funciones condicionales, uso de cadenas, operaciones con cadenas. Ampliar numero de funciones aritméticas (shl, shr, xor, div, mod...).
|
|
|
48
|
Programación / Programación C/C++ / [Ayuda-C] Programación de un analizador léxico-sintáctico
|
en: 6 Agosto 2013, 16:07 pm
|
Buenas a todos, inicio un nuevo POST para pedirles ayuda sobre la programación de un analizador léxico-sintáctico. No entiendo los códigos que vi por ahí, o si los entiendo, son demasiados complejos para implementarlos y hacer una adaptación. Les pondré un ejemplo si no entienden lo que quiero conseguir. Supongamos un fichero de texto como el que sigue: var int a, b, c; string d, e, f; begin print("hola") end
El desglosamiento del programa podría seguir un arbol como: Declarar variables |-a como entero |-b como entero |-c como entero |-d como cadena |-e como cadena |-f como cadena Iniciar ejecucion |- llamar funcion print con argumento hola como cadena Fin ejecucionY que eso me genere unos ciertos opcodes, (no es necesario que el programa genere el arbol anterior), por ejemplo podria ser: 0x00 a (declarar int a), 0x00 b (declarar int b) ... 0x01 d (declarar string d) ... 0x02 "hola" (llamar funcion print con argumento hola). No se como implementar esto en C. ¿Alguien puede ayudarme? Saludos, Miky Gonzalez
|
|
|
49
|
Programación / Programación C/C++ / Re: Pregunta programa en c
|
en: 15 Julio 2013, 14:51 pm
|
A mi, el programa, a mi entender, podría quedar algo como lo que sigue. Sería una muy buena forma de implementarlo y trabajar con punteros y demás, que es lo que más suele costar al principio: Hola amigos mi pregunta es la siguiente, tengo 4 vendedores de los cuales debo guardar uno por uno, nombre, numero de ventas, codigo y descripcion y motrarlo por pantalla y mostrar las ventas totales de todos los vendedores, pero al final debo mostrar cual vendedor tiene el record de haber vendido mas articulos y en eso es que tengo el problema por favor ayudenme a solucionarlo se los agradezco, aqui les dejo lo que eh hecho. #include <stdio.h> #include <stdlib.h> #define NUM_VENDEDORES 4 typedef struct vendedores { char *nombre; unsigned int numero_ventas; unsigned int codigo; char *descripcion; // 255chr + \0 } vendedores_t; int main(int argc, char **argv) { vendedores_t *vendedor = malloc(sizeof(vendedores_t ) * 4); unsigned int bucle_i = 0; while(bucle_i < 4) { printf("Ingrese los datos para vendedor %d (nombre - ventas - codigo - desc): ", bucle_i + 1); scanf("%s %i %i %s", vendedor [bucle_i ]. nombre, &vendedor [bucle_i ]. numero_ventas, &vendedor [bucle_i ]. codigo, vendedor [bucle_i ]. descripcion);
|
|
|
50
|
Programación / Programación C/C++ / Re: Pregunta programa en c
|
en: 15 Julio 2013, 11:18 am
|
Puedes, para practicar, hacer una función para comparar 4 números y retornar el mayor: int retornar_mayor(int a, int b, int c, int d) { if((a > b) && (a > c) && (a > d) return a; else if((b > c) && (b > d)) return b; else if(c > d) return c; else return d; }
Si quieres practicar con el preprocesador de C, puedes hacer que en vez de función sea una directiva. Esto lo puedes hacer como: #define COMPARAR(a, b, c, d) if((a > b) && (a > c) && (a > d) printf("%d", a); \ else if((b > c) && (b > d)) printf("%d", b); \ else if(c > d) printf("%d", c); \ else printf("%d", d);
Para llamar a esta función es muy sencillo; Por ejemplo, podrías hacer: retornar_mayor(vend_1, vend_2, vend_3, vend_4);
Esto te retornará el valor mayor de todos los vendedores, pero no te dirá cuál es. Puede modificar la función para que te retorne una matriz con el nombre del vendedor y su valor: char** lista; // char lista[][]; lista[][] = {{"VENDEDOR", "50"}}; // Un ejemplo en bruto
Para retornar una matriz (sea de la dimensión que sea) debes retornar un puntero hacia la matriz.
|
|
|
|
|
|
|