compiler-construction - code - interpreter programming
¿Puede alguien decirme los conceptos básicos de cómo funciona la programación de computadoras? (13)
¿Qué hace que todas las palabras de un lenguaje de programación realmente hagan algo? Quiero decir, ¿qué está pasando realmente para que la computadora sepa qué significan todas esas palabras? Si verbalmente le digo a mi computadora que haga algo, no lo hace, porque no lo entiende. Entonces, ¿cómo pueden exactamente estas palabras humanas escritas en un lenguaje hacer que la computadora realice alguna actividad deseable?
Básicamente, comienzas con algo simple como:
print("Hello World");
¡Entonces simplemente espolvoreas azúcar sintáctica y tortas mágicas sobre ella hasta que haga lo que quieras!
En el caso más simple, un programa llamado compilador toma las palabras del lenguaje de programación que escribe y las convierte a lenguaje de máquina que la computadora puede entender. Los compiladores entienden un lenguaje de programación específico (C #, Java, etc.) que tiene reglas muy específicas sobre cómo explicarle al compilador lo que quiere que haga.
La mayor parte de lo que se trata de es la interpretación y comprensión de esas reglas. :)
La CPU tiene un registro (una cosa que puede almacenar un número) llamado puntero de instrucción. El puntero de instrucción indica de qué dirección de memoria extraer una instrucción. La CPU extrae una instrucción, la ejecuta y continúa con la siguiente instrucción, a menos que la instrucción que ejecutó dijera que fuera a otro lugar. Estas instrucciones son bastante débiles. Agrega este número a ese número. Guarda este número allí. Tome la siguiente instrucción de allí. Un programa llamado compilador analiza tu programa y lo convierte en código de máquina (me salteo algunos pasos aquí).
Dos libros que le darán una descripción decente de este proceso son SICP y TECS .
La programación es donde toma una serie de pasos que resuelven un problema determinado y los escribe en un idioma determinado que requiere cierta sintaxis. Cuando haya descrito esos pasos en el idioma, puede usar un compilador (según el comentario de Greg) que traduce de ese idioma a uno que la computadora puede interpretar.
El arte radica en asegurarse de que describa los pasos lo suficientemente bien :)
Podría comparar cómo funciona la programación para traducir entre idiomas. Digamos que estabas en una isla desierta con otras 2 personas. Solo hablas francés La persona número 1 (lo llamaremos Fred) solo habla francés y japonés. Persona 2 (Bob) solo habla japonés. Digamos que necesita pedirle a Bob que lo ayude a juntar leña. Imagine en este caso que usted es el programa y Bob es la computadora. Le dices a Fred en francés "¿Puedes decirle a Bob que venga a ayudarme?" Fred traduce al japonés y le pide a Bob que lo ayude. En este caso, Fred sería el compilador. Él traduce la solicitud en algo que Bob puede entender. Esa es una especie de cómo funciona un programa de computadora.
Hay un buen artículo de How Stuff Works que explica las cosas.
Personalmente, no entendía realmente cómo las computadoras podían funcionar de la manera en que lo hacen hasta que tomé una clase de electrónica digital. Antes de eso, la idea de cómo las computadoras podrían funcionar para mí. Después de que construí un contador binario, todo tenía sentido.
Como la gente ya está notando, hay algún preprograma (generalmente un "compilador") que traduce las palabras de su programa en un lenguaje más extenso de "nivel inferior" llamado "código de máquina".
El código máquina consiste en instrucciones muy simples que ya son "entendidas" por (o al menos tienen sentido en términos de) el procesador subyacente. Por ejemplo, una instrucción que copia datos de una ubicación de memoria, y en una parte especial del procesador (llamada "acumulador" donde se puede hacer aritética simple) o una instrucción para agregar el contenido de dos de los espacios. en el acumulador.
Los programas complejos y sofisticados que ve (incluidos los compiladores e intérpretes de lenguajes de nivel superior) son todos, en última instancia, construidos a partir de estas simples instrucciones que se ejecutan millones de veces.
Muy simplemente, la programación informática es el acto de darle a la computadora un conjunto de instrucciones en un lenguaje que puede entender. Los programadores normalmente escriben instrucciones en un lenguaje de programación de alto nivel, y esas instrucciones luego se traducen al lenguaje binario que la computadora entiende. Los programas que hacen esta traducción se llaman compiladores.
Todo comienza con la CPU o el procesador. Cada tipo de procesador tiene un conjunto definido de instrucciones que puede realizar. Estas instrucciones operan sobre los ceros y los ceros, que a su vez representan lo que sea que usted desee: números, letras, incluso las instrucciones mismas.
En el nivel más bajo, un cero está determinado por la presencia de un cierto voltaje (generalmente cerca de 0V) en un transistor y un 1 es la presencia de un voltaje diferente (depende de la CPU, digamos 5V)
Las instrucciones de la máquina en sí son conjuntos de ceros y unos ubicados en ubicaciones especiales llamadas registros en el procesador, el procesador toma las instrucciones y sus operandos de ubicaciones específicas y realiza la operación, colocando el resultado en otra ubicación, luego va a buscar el siguiente instrucción, etc., hasta que se agote la instrucción o se apague.
Un simple ejemplo. Digamos que la instrucción de la máquina 001 significa agregar dos números.
Luego escribes un programa que agrega dos números, generalmente así:
4 + 5
Luego pasa este texto a un compilador que generará el código de máquina adecuado para el procesador en el que ejecutará el programa (nota al margen, puede compilar código para que se ejecute en un procesador diferente del que está ejecutando actualmente, es un proceso llamado compilación cruzada y es útil, por ejemplo, en plataformas integradas). Bueno, el compilador terminará generando, más o menos,
001 00000100 00000101
con código de máquina repetitivo adicional para colocar la instrucción 001 en el siguiente registro de instrucción (puntero de instrucción) y los números codificados en binario en los registros de datos (o RAM).
El proceso de generación de código de máquina a partir de los lenguajes estructurados es bastante complejo y pone límites a la forma en que estos lenguajes pueden llegar a ser normales. Es por eso que no se puede escribir un programa en inglés, hay demasiada ambigüedad para que un compilador pueda generar la secuencia correcta de ceros y unos.
Las instrucciones que las CPU pueden ejecutar son bastante básicas y simples, además, división, negación, lectura desde la RAM, lugar en la RAM, lectura desde el registro, y así sucesivamente.
La siguiente pregunta es, ¿cómo pueden estas simples instrucciones sobre los números generar todas las maravillas que vemos en la informática (internet, juegos, reproductores de películas, etc.)?
Básicamente se reduce a la creación de modelos adecuados, por ejemplo, un motor de juegos 3D tiene un modelo matemático que representa el mundo del juego y puede calcular la posición / colisiones de los objetos del juego basados en él.
Estos modelos se basan en muchas de estas instrucciones pequeñas, y aquí es donde los lenguajes de alto nivel (que no son códigos de máquina) realmente brillan porque elevan el nivel de abstracción y luego puede pensar más de cerca en el modelo que desea implementar , lo que le permite razone fácilmente sobre cosas como cómo calcular de manera eficiente la siguiente posición que el soldado va a estar basado en la entrada recibida del controlador en lugar de evitar que razone fácilmente porque está demasiado ocupado tratando de no olvidar un 0.
Un momento crucial ocurrió con el salto del lenguaje ensamblador (un lenguaje muy similar al código de máquina, fue el primer lenguaje de programación y es específico de CPU. Cada instrucción de ensamblaje se traduce directamente en código de máquina) a C (que es portátil entre diferentes CPU y a un nivel más alto de abstracción que ensamblado: cada línea de código C representa muchas instrucciones de código de máquina). Este fue un gran aumento de productividad para los programadores, ya no tuvieron que trasladar programas entre diferentes CPU, y pudieron pensar mucho más fácilmente sobre los modelos subyacentes, lo que condujo al aumento continuo de complejidad en el software que hemos visto (e incluso demandado) desde la década de 1970 hasta hoy.
El siguiente eslabón perdido es cómo controlar qué hacer con esa información y cómo recibir información de fuentes externas, por ejemplo, mostrar imágenes en la pantalla o escribir información en un disco duro, o imprimir una imagen en una impresora, o recibir golpes de tecla de una teclado. Todo esto es posible gracias al resto del hardware presente en la computadora que se controla de forma similar a la de la CPU, coloca datos e instrucciones en ciertos transistores de la tarjeta gráfica o la tarjeta de red o el disco duro o el RAM. La CPU tiene instrucciones que le permitirán colocar algunos datos o instrucciones en (o leer información de) la ubicación correcta de diferentes piezas de hardware.
Otra cosa relevante para la existencia de lo que tenemos hoy es que todas las computadoras modernas vienen con grandes programas llamados sistemas operativos que manejan todo lo básico como hablar con hardware y manejo de errores, como lo que sucede si un programa se bloquea y así sucesivamente. Además, muchos entornos de programación modernos vienen con una gran cantidad de código ya escrito (bibliotecas estándar) para manejar muchas tareas básicas, como dibujar en una pantalla o leer un archivo. Estas bibliotecas, a su vez, le pedirán al sistema operativo que hable con el hardware en su nombre.
Si no estuvieran disponibles, la programación sería una tarea muy difícil y tediosa ya que cada programa que escriba tendrá que volver a crear el código para dibujar una sola letra en la pantalla o leer un bit de cada tipo específico de disco duro, por ejemplo.
Parece que me dejé llevar, espero que entiendas algo de esto :-)
Un lenguaje de programación de computadora es en realidad un lenguaje muy abstraído que se convierte en un lenguaje muy básico que las computadoras realmente entienden.
Básicamente, las computadoras solo entienden el lenguaje de máquina, que es un lenguaje básico implementado en binario (1 y 0). Un nivel superior a este es el lenguaje ensamblador, que es un lenguaje muy primitivo que es al menos legible para humanos.
En un lenguaje de alto nivel, podríamos tener algo como:
Person.WalkForward(10 steps)
En el código de máquina, sería:
Lift Persons Left Foot Up
Lean Forward
Place Left Foot Down
Lift Right Foot up
Lean Forward
Place Right Foot Down
etc
Ahora, obviamente, nadie quiere escribir programas que le digan a la computadora cada pequeña cosa repetitiva para hacer, entonces tenemos herramientas llamadas compiladores.
Un compilador toma un lenguaje de nivel superior que es más fácil de entender para un humano y lo convierte en código de máquina para que la computadora pueda ejecutarlo.
Varias personas ya han proporcionado resúmenes del proceso de traducción desde un lenguaje de programación típico hasta un código de máquina real que un procesador puede ejecutar.
Para comprender este proceso, es útil tener una idea concreta de lo que realmente es programar a nivel de código máquina. Una vez que comprendes lo que el procesador puede hacer, es más fácil entender las construcciones de programación de alto nivel que las abreviaturas que son.
Pero desafortunadamente, escribir código de máquina para una computadora de escritorio no es muy divertido.
Como alternativa, hay un gran juego antiguo llamado Corewar en el que se escriben pequeños programas utilizando un lenguaje de máquina simplificado. Estos programas luego luchan entre sí por la supervivencia. Puede escribir programas básicos en el lenguaje de máquina sin procesar, y luego hay un sistema de macros para que no tenga que repetirse demasiado, y ese es el primer paso hacia un lenguaje completo.
Otra cosa fácil, gratificante, pero de bajo nivel es programar un controlador incrustado simple como un Arduino . Hay muchas presentaciones fáciles como esta disponible. Todavía utilizará un compilador, pero el código de máquina resultante es más fácil de entender (si lo desea) porque las capacidades del procesador son mucho más simples.
Ambas son excelentes maneras de tener una idea de cómo funcionan realmente las computadoras digitales.
La computadora tiene una cantidad predeterminada de instrucciones; Lo que ya sabe cómo hacer. Un programa de computadora es simplemente una lista de instrucciones que la computadora ejecutará secuencialmente.
Los primeros programas se escribieron directamente en lenguaje de máquina. Los programadores, para facilitar sus vidas, comenzaron a crear abstracciones para simplificar los programas que necesitan escribir. Con el tiempo, se agregan más y más abstracciones, como capas de una cebolla, pero todo se reduce a esencialmente lo mismo: ejecutar una serie de instrucciones.
Si desea aprender sobre programación sin centrarse en compiladores, tecnología, etc., obtendrá una buena indicación de qué es un programa cuando comience a crear escenas en 3D en Alicia . Alice es libre de la Universidad Carnegie Mellon. Terminas aprendiendo a programar sin intentar aprender a programar.
Sin embargo, si desea obtener más información acerca de los detalles técnicos, su mejor opción sería mirar algunos libros de texto de intro compi-sci university. La siguiente aplicación de How C Programming también podría darle algunas respuestas.
Tengo dos sugerencias locas. ¡Retrocede en el tiempo!
1. Obtenga una calculadora programable.
Una calculadora programable es una calculadora regular, puede hacer lo de siempre con ella: ingrese los números, ingrese los signos de operación y, después de presionar la tecla equel, puede leer el resultado en la pantalla pequeña. Además, la calculadora programable puede almacenar secuencias cortas de pulsaciones de teclas como un programa, que luego puede "reproducirse" con una sola pulsación de tecla. Digamos, estableces esta secuencia como un programa (una instrucción por línea):
(Start)
*
2
+
1
=
(Stop)
Ahora tiene una operación personalizada: al presionar la tecla "programa" (oa la que haya asignado) ejecutará la secuencia sin su ayuda adicional y se multiplicará el contenido de la pantalla por 2 y se agregará 1 - este es un ¡programa!
Más tarde puede probar técnicas más avanzadas: almacenar resultados temporales en la memoria, bifurcar en el resultado.
Pros:
- Una calculadora es un ambiente familiar. Ya tienes lo básico.
- Es sencillo. No tiene que aprender muchas instrucciones y técnicas de programación.
- Los lenguajes de programación modernos están lejos de la tierra, mientras que las calculadoras programables "están en él". Aprenderá los fundamentos: memoria, rama, operaciones elementales. Las computadoras funcionan de la misma manera (en el nivel de lenguaje de la máquina).
- Encontrarás problemas de bajo nivel: memoria, división por cero.
- Es extremadamente genial.
Contras:
- Es obsoleto Tienes que aprender un lenguaje de programación moderno, que será diferente.
- Es incómodo (hm, en cambio es un profesional: no puedes usar juguetes cómodos de hacer clic y jugar). Quizás ni siquiera puedas guardar tu código.
- No es una tarea trivial obtener uno. Puedes probar E-Bay. Además, no habrá problemas con la documentación, la mayoría de los modells tienen grandes grupos de usuarios en Internet.
La mejor opción en mi humilde opinión, la TI-59 .
2. Aprenda el lenguaje BASIC con la ayuda de un emulador.
Cuando enciende una máquina que tiene un intérprete de lenguaje BASIC incorporado , está lista para aceptar sus comandos y funciona tal como escribe. Primero, puedes probar algunas instrucciones en modo comando, por ejemplo:
PRINT 5*4
Imprimirá "20" en la línea siguiente, guau. Si ha jugado lo suficiente en modo comando, puede organizar las instrucciones en programas, luego puede ejecutar, editar, mejorar.
Pros:
- BASIC es un lenguaje de programación real, diseñado para la educación.
- Cuando más tarde conozcas un lenguaje de programación moderno y descubras las diferencias, verás el progreso de las técnicas de programación (por ejemplo, procedimientos, estructuras, etc.) de los últimos 30 años.
- Es genial, especialmente si obtienes uno real, no solo un emulador.
Contras
- Es obsoleto Han pasado casi 30 años desde esa edad.
- Las máquinas antiguas son sistemas compactos y cerrados. No hay archivos (en la forma en que los usamos hoy), carpetas, tipos de archivos, puede confundir a los principiantes.
Mi sistema BASIC favorito es el Commodore 16 (Plus / 4) , que es muy similar al famoso C64. pero más cómodo. Prefiero el emulador YAPE , puede guardar / cargar instantáneas de memoria o programas BASIC para archivar.
Un buen libro que habla de computadoras para no ingenieros es ''Código'' de Charles Petzold . No recuerdo exactamente si cubre exactamente su pregunta, pero creo que sí. Si estás lo suficientemente interesado como para ir más lejos, es una buena opción.