¿Puede un programador experto en lenguaje ensamblador realizar los trabajos realizados por otros lenguajes de programación?

¿Cuál es el panorama general?

La programación, a veces denominada codificación, es una actividad básica para la informática. Si bien este libro no le enseñará cómo programar (le hemos dado algunos enlaces a sitios que pueden hacer esto en la introducción), vamos a ver qué es un lenguaje de programación y cómo los informáticos le dan vida a un lenguaje . Desde el punto de vista del programador, escriben algunas instrucciones y la computadora las sigue. Pero, ¿cómo sabe la computadora qué hacer? Tenga en cuenta que puede estar utilizando uno de los muchos lenguajes como Python, Java, Scratch, Basic o C #, pero las computadoras solo tienen el hardware para seguir instrucciones en un idioma en particular, que generalmente es un “código de máquina” muy simple que Es difícil para los humanos leer y escribir. Y si inventa un nuevo lenguaje de programación, ¿cómo le dice a la computadora cómo usarlo?

En este capítulo veremos qué sucede cuando escribe y ejecuta un programa, y ​​cómo esto afecta la forma en que distribuye el programa para que otros lo usen.

Comenzamos con una subsección opcional sobre qué es la programación, para aquellos que nunca han programado antes y quieren tener una idea sobre qué es un programa. Se proporcionan ejemplos de programas muy simples en Python, que pueden ejecutarse y modificarse ligeramente. Trabajar en esta sección debería brindarle el conocimiento suficiente para que el resto de este capítulo tenga sentido; no le enseñaremos cómo programar, pero podrá seguir el proceso que usan los programadores para ejecutar un programa. Siéntase libre de omitir esta sección si ya conoce un poco sobre programación.

Luego sigue una subsección sobre en qué se enfoca este capítulo. Todos deberían leer esa sección.

1.1. ¿Qué es la programación?

Nota: Esta sección está destinada a aquellos que no están familiarizados con la programación. Si ya sabe un poco sobre programación, no dude en pasar por alto esta sección. De lo contrario, le dará una visión general rápida para que el resto del capítulo tenga sentido.

Un ejemplo del tipo de programa más simple es el siguiente: tiene cinco instrucciones (una en cada línea) que se siguen una tras otra.

impresión(“**********************************************” )
impresión(“**********************************************” )
print (“** Bienvenido a la programación de computadoras, Estudiante **”)
impresión(“**********************************************” )
impresión(“**********************************************” )

Este programa está escrito en un lenguaje llamado Python, y cuando se ejecuta, imprimirá el siguiente texto en la pantalla

************************************************
************************************************
*** Bienvenido a la programación de computadoras, Estudiante ***
************************************************
************************************************

Para ejecutar un programa Python, necesitamos algo llamado intérprete de Python. Un intérprete de Python puede leer su programa y procesarlo. A continuación hay un intérprete de Python que puede usar para ejecutar sus propios programas. Si tiene un intérprete de Python instalado en su computadora (pregunte a su maestro si está siguiendo este libro para una clase y está confundido) y sabe cómo iniciarlo y ejecutar programas en él, puede usarlo.

Programa

Salida

Intente cambiar el programa para que diga su nombre en lugar de Estudiante . Cuando creas que tienes razón, intenta ejecutar el programa nuevamente para ver. Asegúrese de no eliminar las comillas dobles o los paréntesis (corchetes) en el programa por error. ¿Qué sucede si deletreaste mal “programación”? ¿La computadora lo corrige? Si está completamente atascado, pídale ayuda a su maestro antes de continuar.

Esperemos que hayas descubierto cómo hacer que el programa imprima tu nombre. También puede cambiar los asteriscos (*) a otros símbolos. ¿Qué sucede si eliminas una de las comillas dobles o uno de los paréntesis? ¡Intentalo!

Si cambia un símbolo crítico en el programa, probablemente encontrará que el intérprete de Python da un mensaje de error. En el intérprete de Python en línea vinculado a lo anterior, dice “ParseError: entrada incorrecta en la línea 1”, aunque diferentes intérpretes expresarán el error de diferentes maneras. Si tiene problemas para corregir el error nuevamente, simplemente copie el programa nuevamente en Python desde arriba.

Sin embargo, los lenguajes de programación pueden hacer mucho más que imprimir texto. El siguiente programa puede imprimir múltiplos de un número. Intenta ejecutar el programa.

print (“Voy a imprimir los primeros 5 múltiplos de 3”)
para i en rango (5):
imprimir (i * 3)

La primera línea es una declaración impresa, como las que vio anteriormente, que simplemente le dice al sistema que coloque el mensaje en la pantalla. La segunda línea es un bucle , que dice que repita las líneas después de 5 veces. Cada vez que se repite, el valor de i cambia. es decir, la primera vez que soy 0, luego 1, luego 2, luego 3 y finalmente 4. Puede parecer extraño que pase de 0 a 4 en lugar de 1 a 5, pero a los programadores les gusta contar desde 0 ya que las cosas funcionan un poco más simple. La tercera línea dice que imprima el valor actual de i multiplicado por 3 (porque queremos múltiplos de 3). Tenga en cuenta que no hay comillas dobles alrededor de la última declaración de impresión, ya que solo se usan cuando queremos imprimir algo literalmente como texto. Si los pusiéramos, este programa imprimiría el texto “i * 3” 5 veces en lugar del valor que queremos.

Intente realizar los siguientes cambios en el programa.

  • Haga que imprima múltiplos de 5 en lugar de 3. Sugerencia: necesita cambiar más que solo la primera línea, también deberá hacer un cambio en la tercera línea.
  • Haga que imprima los primeros 10 múltiplos en lugar de los primeros 5. ¡Asegúrese de que imprima 10 múltiplos y no 9 u 11!

También puede recorrer una lista de datos. Intenta ejecutar el programa a continuación. ¡Generará una serie de mensajes de “spam”, uno dirigido a cada persona en la lista de destinatarios!

Tenga en cuenta que el símbolo # le dice a la computadora que debe ignorar la línea, ya que es un comentario para el programador.

# Lista de destinatarios para generar mensajes
spam_recipients = [“Heidi”, “Tim”, “Pondy”, “Jack”, “Caitlin”, “Sam”, “David”]
# Ir a través de cada destinatario
para destinatario en spam_recipients:
# Escriba la carta para el destinatario actual
print (“Estimado” + destinatario + “, \ n”)
print (“Has tenido éxito en el sorteo al azar para todas las personas”)
print (“que han caminado sobre un terreno específico ubicado a 2 metros”)
print (“desde la entrada del camino de ingeniería a la Universidad de Canterbury. \ n”)
print (“Por tener éxito en este sorteo,” + destinatario + “, gana”)
print (“un premio de 10 millones de kilogramos de chocolate !!! \ n”)
print (“Y” + destinatario + “si nos llama en los próximos 10 minutos”)
print (“obtendrás un bono de 5 millones de kilogramos de chocolate !!! \ n”)
print (“\ n \ n \ n”) # Coloca algunas líneas nuevas entre los mensajes

Intenta cambiar los destinatarios o la carta. Mire cuidadosamente todos los símbolos que se usaron para incluir el nombre del destinatario en la carta.

  • Jerga Buster : Sintaxis ▼

Los programas también pueden usar variables para almacenar los resultados de los cálculos, recibir información del usuario y tomar decisiones (llamadas condicionales , como declaraciones if ). Intenta ejecutar este programa. Ingrese una cantidad de millas para convertir cuando se le solicite. No ponga unidades en el número que ingrese; por ejemplo solo pon “12”.

print (“Este programa convertirá millas a kilómetros”)
number_of_miles = int (input (“Número de millas:”))
si número_de_miles <0:
print (“Error: ¡Solo puede convertir un número positivo de millas!”)
más:
number_of_kilometers = number_of_miles / 0.6214
print (“Número calculado de kilómetros …”)
print (número_de_kilómetros)

La primera línea es una declaración impresa (¡con la que ya debería estar muy familiarizado!). La segunda línea le pide al usuario una cantidad de millas que se convierten del texto de entrada (llamado cadena) a un entero, la tercera línea usa un if para verificar si el número ingresado fue menor que 0, para que pueda imprimir un error si es así. De lo contrario, si el número estaba bien, el programa salta a la sección else (el error no se imprime porque el if no era verdadero), calcula el número de kilómetros (hay 0.6214 kilómetros en una milla), lo almacena en una variable llamada number_of_kilometers para referencia posterior, y luego la última línea lo imprime. Nuevamente, no tenemos comillas alrededor de number_of_kilometers en la última línea, ya que queremos imprimir el valor almacenado en la variable number_of_kilometers. Si esto no tiene sentido, no te preocupes. No se espera que sepa cómo programar para este capítulo, esta introducción solo tiene la intención de que tenga una idea de lo que es un programa y las cosas que puede hacer.

Si está interesado, puede modificar este programa para calcular otra cosa, como libras a kilogramos o Fahrenheit a grados Celsius. Puede ser mejor usar un intérprete de Python instalado en su computadora en lugar de la versión web, ya que la versión web puede dar mensajes de error muy inútiles cuando su programa tiene un error (¡aunque todos los intérpretes dan mensajes de error terribles al menos algunas veces!)

Los programas pueden hacer muchas más cosas, como tener una interfaz gráfica de usuario (como la mayoría de los programas de computadora con los que estará familiarizado), poder imprimir gráficos en una pantalla o poder escribir y leer archivos en la computadora en orden para guardar información entre cada vez que ejecuta el programa.

1.2. ¿A dónde vamos?

Cuando ejecutó los programas, podría haber parecido bastante mágico que la computadora pudiera darle la salida al instante. Sin embargo, detrás de escena, la computadora estaba ejecutando sus programas de ejemplo a través de otro programa para convertirlos en una forma que pudiera tener sentido y luego ejecutar.

En primer lugar, es posible que se pregunte por qué necesitamos idiomas como Python y por qué no podemos dar instrucciones en inglés a las computadoras. Si escribimos en la computadora “Ok, computadora, imprímeme los primeros 5 múltiplos de 3”, no hay razón para que pueda entender. Para empezar, no sabría qué es un “múltiple”. Y ni siquiera sabría cómo hacer esta tarea. A las computadoras no se les puede decir qué significa cada palabra, y no pueden saber cómo realizar todas las tareas posibles. Comprender el lenguaje humano es una tarea muy difícil para una computadora, como descubrirá en el capítulo de Inteligencia Artificial. A diferencia de los humanos que comprenden el mundo y ven el significado, las computadoras solo pueden seguir las instrucciones precisas que usted les da. Por lo tanto, necesitamos lenguajes que sean limitados y sin ambigüedades en los que la computadora “entienda” las instrucciones. Estas pueden usarse para dar instrucciones a la computadora, como las de la sección anterior.

Sin embargo, no es tan simple, una computadora no puede ejecutar instrucciones dadas directamente en estos idiomas. En el nivel más bajo, una computadora tiene que usar hardware físico para ejecutar las instrucciones. La aritmética, como la suma, la resta, la multiplicación y la división, o las comparaciones simples como menor, mayor o igual que se realizan en números representados en binario al poner electricidad a través de chips físicos de computadora que contienen transistores. La salida también es un número representado en binario. Construir un circuito rápido y barato para hacer operaciones aritméticas simples como esta no es tan difícil, pero el tipo de instrucciones que la gente quiere dar a las computadoras (como “imprimir la siguiente oración” o “repetir las siguientes 100 veces”) es mucho más difícil de construir circuitos para.

  • Jerga Buster : Binario ▼

Entonces, en lugar de construir computadoras que puedan comprender estas instrucciones de alto nivel que se encuentran en lenguajes como Python (o Java, Basic, JavaScript, C, etc.), creamos computadoras que pueden seguir un conjunto muy limitado de instrucciones, y luego escribimos programas que convierten las instrucciones en los idiomas estándar en los que las personas escriben programas en instrucciones simples que los circuitos pueden llevar a cabo directamente. El lenguaje de estas sencillas instrucciones es un lenguaje de programación de bajo nivel, a menudo denominado código de máquina.

La conversión de un lenguaje de alto nivel a un bajo nivel puede implicar la compilación , que reemplaza las instrucciones de alto nivel con instrucciones de código de máquina que luego se pueden ejecutar, o se puede hacer mediante la interpretación , donde cada instrucción se convierte y sigue una por una, a medida que se ejecuta el programa. En realidad, muchos lenguajes usan una mezcla de estos, a veces compilando un programa en un lenguaje intermedio y luego interpretándolo (Java hace esto). El lenguaje que vimos anteriormente, Python, es un lenguaje interpretado. Se compilan otros lenguajes como C ++. Hablaremos más sobre compilar e interpretar más tarde.

Los diferentes niveles de lenguajes de programación son una abstracción que permite a los programadores preocuparse solo por los detalles necesarios de un solo nivel. Los programadores de alto nivel pueden producir programas sofisticados en Python sin el conocimiento experto de lenguajes de bajo nivel como MIPS, x86 o ARM. Los programadores de bajo nivel pueden producir programas integrados en ARM sin el conocimiento experto de los circuitos electrónicos.

Comenzaremos mirando los lenguajes de bajo nivel y cómo las computadoras realmente llevan a cabo las instrucciones en ellos, luego veremos algunos otros lenguajes de programación que los programadores usan para dar instrucciones a las computadoras, y finalmente hablaremos sobre cómo convertimos los programas que fueron escritos por humanos en un lenguaje de alto nivel en un lenguaje de bajo nivel que la computadora puede llevar a cabo.

2. Código de máquina (idiomas de bajo nivel)

Una computadora tiene que llevar a cabo instrucciones sobre circuitos físicos. Estos circuitos contienen transistores dispuestos de manera especial que proporcionarán una salida correcta basada en las entradas.

Los datos como los números (representados mediante binario) deben guardarse en lugares de almacenamiento llamados registros mientras el circuito los procesa. Los registros se pueden establecer en valores, o los datos de la memoria se pueden colocar en los registros. Una vez en los registros, se pueden sumar, restar, multiplicar, dividir o verificar la igualdad, mayor o menor que. La salida se coloca en un registro, donde se puede recuperar o utilizar en aritmética adicional.

Todas las computadoras tienen un lenguaje de código de máquina (comúnmente conocido como un conjunto de instrucciones) que se usa para decirle a la computadora que coloque valores en los registros, para llevar a cabo la aritmética con los valores en ciertos registros y poner el resultado en otro registro específico como el que hablado anteriormente. El código de máquina también contiene instrucciones para cargar y guardar valores de la memoria (dentro o fuera de los registros), saltar a una línea determinada en el programa (es decir, antes o después de la línea actual), o saltar a la línea solo si se cumple la condición (haciendo una comparación específica de los valores en los registros). También hay instrucciones para manejar entradas / salidas simples e interactuar con otro hardware en la computadora.

Las instrucciones son bastante diferentes a las que habrá visto antes en idiomas de alto nivel. Por ejemplo, el siguiente programa está escrito en un lenguaje de máquina llamado MIPS; que se usa en algunos sistemas informáticos integrados. Usaremos MIPS en ejemplos a lo largo de este capítulo.

Comienza agregando 2 números (que se han puesto en los registros $ t0 y $ t1) e imprimiendo el resultado. Luego imprime “¡Hola Mundo!” ¡No te preocupes, no vamos a hacerte aprender cómo programar realmente en este idioma! Y si realmente no comprende el programa, ¡también está bien porque muchos ingenieros de software tampoco lo harían! (¡Te lo mostramos para ayudarte a apreciar los idiomas de alto nivel!)

.datos
str: .asciiz “\ nHola Mundo! \ n”
# Puedes cambiar lo que hay entre comillas si quieres

.texto
.globl principal

principal:
# Haz la adición
# Para esto, primero tenemos que poner los valores
# para agregar a los registros ($ t0 y $ t1)
# Puede cambiar los 30 siguientes a otro valor
li $ t0, 30
# Puede cambiar los 20 siguientes a otro valor
li $ t1, 20

# Ahora podemos agregar los valores en $ t0
# y $ t1, colocando el resultado en el registro especial $ a0
agregue $ a0, $ t0, $ t1

# Configurar para imprimir el valor en $ a0.
# A 1 en $ v0 significa que queremos imprimir un int
li $ v0, 1

# La llamada al sistema analiza lo que está en $ v0
# y $ a0, y sabe imprimir lo que está en $ a0
syscall

# Ahora queremos imprimir Hello World
# Entonces cargamos la (dirección de) la cadena en $ a0
la $ a0, str

# Y ponga un 4 en $ v0 para significar imprimir una cadena
li $ v0, 4

# Y al igual que antes de syscall mira
# $ v0 y $ a0 y sabe imprimir la cadena
syscall

# Muy bien terminar el programa
li $ v0, 0
jr $ ra

Puede ejecutar este programa usando un emulador MIPS usando este interactivo:

Haga clic para cargar el ensamblador MIPS

Copie y pegue la salida en el cuadro “Salida del ensamblador” en el cuadro de este simulador interactivo:

Haga clic para cargar MIPS Simulator

Una vez que tenga el programa funcionando, intente cambiar los valores que se agregan. Los comentarios le dicen dónde están estos números que se pueden cambiar. También debe poder cambiar la cadena (texto) que se imprime sin demasiados problemas también. Como desafío, ¿puedes hacerlo para que reste en lugar de sumar los números? Pista: los nombres de las instrucciones son siempre muy cortos. Lamentablemente, no podrá hacer que se multiplique o divida con este simulador, ya que actualmente no es compatible. Recuerde que para volver a ejecutar el programa después de cambiarlo, deberá seguir los pasos 1 y 2 nuevamente.

Tal vez se pregunte por qué tiene que llevar a cabo estos dos pasos. Debido a que las computadoras funcionan en 1 y 0, las instrucciones simplemente deben convertirse en hexadecimales. Hexadecimal es una notación abreviada para números binarios. ¡No confundas este proceso compilando o interpretando! A diferencia de estos, es mucho más simple ya que, en general, cada instrucción del código fuente termina siendo una línea en el hexadecimal.

Una cosa que podría haber notado al leer sobre las posibles instrucciones es que no hay instrucciones de bucle en MIPS. Sin embargo, utilizando varias instrucciones, en realidad es posible escribir un bucle usando este lenguaje simple. Lea otra vez el párrafo que describe las diversas instrucciones en MIPS. ¿Tienes alguna idea sobre cómo resolver este problema? ¡Requiere ser bastante creativo!

¡Saltar a una línea y saltar a una línea si se cumple una condición puede usarse para hacer bucles! Un programa muy simple podemos escribir que requiere un bucle es la que cuenta regresiva de cinco y luego dice “Go !!!!” una vez que se pone a uno. En Python podemos escribir fácilmente este programa en tres líneas.

# Comience en 5, haga una cuenta regresiva de 1 cada vez y pare cuando lleguemos a 0
para número en rango (5, 0, -1):
imprimir (número)
imprimir (“GO !!!!!”)

Pero en MIPS, no es tan sencillo. Necesitamos poner valores en registros, y necesitamos construir el ciclo a partir de las declaraciones de salto. En primer lugar, ¿cómo podemos diseñar el bucle?

Y el programa completo de MIPS para esto es el siguiente. Puedes irte y cambiarlo.

# Definir las cadenas de datos
.datos
go_str: .asciiz “GO !!!!! \ n”
nueva_línea: .asciiz “\ n”

.texto
# ¿Dónde deberíamos comenzar?
.globl principal

principal:
# Ponga nuestro valor inicial 5 en el registro $ t0. Lo actualizaremos a medida que avanzamos
li $ t0, 5
# Ponga nuestro valor de detención 0 en el registro $ t1
li $ t1, 0

# Esta etiqueta solo se usa para que los saltos se refieran a
start_loop:
# Esto dice que si los valores en $ t0 y $ t1 son los mismos,
# debería saltar a la etiqueta end_loop. Este es el
# condición del bucle principal.
beq $ t0, $ t1, end_loop
# Estas tres líneas preparan e imprimen el int actual
# Se debe mover a $ a0 para la impresión
mover $ a0, $ t0
li $ v0, 1
syscall
# Estas tres líneas imprimen un nuevo carácter de línea para que
# cada número está en una nueva línea
li $ v0, 4
la $ a0, nueva_línea
syscall
# Agregar -1 al valor en $ t0, es decir, disminuirlo en 1
addi $ t0, $ t0, -1
# Volver a la etiqueta start_loop
j start_loop

# Esta es la etiqueta del bucle final al que saltamos cuando el bucle es falso
end_loop:
# Estas tres líneas imprimen la cadena “GO !!!!”
li $ v0, 4
la $ a0, go_str
syscall
# Y estas 2 líneas hacen que el programa salga bien
li $ v0, 0
jr $ ra

¿Puedes cambiar el programa Python para que cuente desde 10? ¿Qué tal si se detiene a las 5? (Puede que tenga que intentarlo un par de veces, ya que es algo contrario a la intuición. Recuerde que cuando i es el número de detención, se detiene allí y no ejecuta el ciclo para ese valor). ¿Y qué hay de disminuir por 2 en lugar de 1? ¿Y cambiando la cadena (texto) que se imprime al final?

Probablemente haya encontrado que el programa Python no es demasiado difícil de modificar. Vea si puede hacer estos mismos cambios en el programa MIPS.

Si eso fue demasiado fácil para usted, ¿puede hacer que ambos programas impriman “GO !!!!” dos veces en lugar de una vez? (no tienes que usar un bucle para eso). Y si ESO fue demasiado fácil, ¿qué hay de hacer que cada programa imprima “¡VAYA!” 10 veces? Debido a que repetir una línea en un programa 10 veces sin un bucle sería una práctica de programación terrible, necesitaría usar un bucle para esta tarea.

Lo más probable es que esté bastante confundido en este momento y no pueda modificar el programa MIPS con todos estos cambios sugeridos. Y si usted tiene un bucle adicional en sus MIPS imprimir correctamente el programa “GO !!!” 10 veces, entonces usted está bien en su manera de ser un buen programador!

Entonces, ¿cuál era el punto de todo esto? Estas instrucciones de bajo nivel pueden parecer tediosas y un poco tontas, pero la computadora puede ejecutarlas directamente en hardware debido a su simplicidad. Un programador puede escribir un programa en este idioma si conoce el idioma, y ​​la computadora podría ejecutarlo directamente sin realizar ningún procesamiento adicional. Sin embargo, como probablemente se haya dado cuenta, es extremadamente lento tener que programar de esta manera. Mover elementos dentro y fuera de los registros, implementar bucles utilizando declaraciones de salto y ramificación, e imprimir cadenas y números enteros usando un patrón de tres líneas que probablemente nunca habrías adivinado que era para imprimir si no te hubiéramos dicho que deja aún más oportunidades para errores en el programa. Sin mencionar que los programas resultantes son extremadamente difíciles de leer y comprender.

Debido a que las computadoras no pueden ejecutar directamente las instrucciones en los lenguajes que les gustan a los programadores, los lenguajes de programación de alto nivel por sí mismos no son suficientes. La solución a este problema de diferentes necesidades es usar un compilador o un intérprete que pueda convertir un programa en el lenguaje de programación de alto nivel que el programador usó en el código de máquina que la computadora puede entender.

En estos días, pocos programadores programan directamente en estos idiomas. En los primeros días de las computadoras, los programas escritos directamente en lenguaje máquina tendían a ser más rápidos que los compilados a partir de lenguajes de alto nivel. Esto se debió a que los compiladores no eran muy buenos para minimizar la cantidad de instrucciones en lenguaje de máquina, denominadas optimización , y las personas capacitadas para escribir en código de máquina eran mejores en eso. Sin embargo, en la actualidad, los compiladores se han hecho mucho más inteligentes y pueden optimizar el código mucho mejor que la mayoría de las personas. Escribir un programa directamente en código de máquina puede resultar en un programa que está menos optimizado que uno que se compiló de un lenguaje de alto nivel. ¡No ponga en su informe que los idiomas de bajo nivel son más rápidos!

Esta no es la historia completa; El código de máquina MIPS descrito aquí es algo llamado Arquitectura de conjunto de instrucciones reducidas (RISC). En la actualidad, muchas computadoras usan una Arquitectura de conjunto de instrucciones complejas (CISC). Esto significa que los chips de la computadora pueden ser un poco más inteligentes y pueden hacer más en un solo paso. Sin embargo, esto está más allá del alcance de este libro, y comprender el tipo de cosas que puede hacer el código de máquina RISC, y las diferencias entre MIPS y los lenguajes de alto nivel están bien en este nivel, y están bien para la mayoría de los científicos informáticos e ingenieros de software.

En resumen, requerimos lenguajes de programación de bajo nivel porque la computadora puede entenderlos, y requerimos lenguajes de programación de alto nivel porque los humanos pueden entenderlos. Una sección posterior habla más sobre compiladores e intérpretes; programas que se utilizan para convertir un programa escrito en un lenguaje de alto nivel (para humanos) en un lenguaje de bajo nivel (para computadoras).

3. Una babel de lenguajes de programación

Hay muchos lenguajes de programación diferentes. Aquí hemos incluido un pequeño subconjunto de idiomas, para ilustrar el rango de propósitos para los que se usan los idiomas. Hay muchos, muchos más idiomas que se utilizan para diversos fines, y tienen un fuerte seguimiento de las personas que los encuentran particularmente útiles para sus aplicaciones.

Para obtener una lista mucho más grande, puede consultar Wikipedia aquí.

3.1. Pitón

Python es un lenguaje ampliamente utilizado, que también se ha vuelto muy popular como lenguaje de enseñanza. Muchas personas aprenden Python como su primer lenguaje de programación. En la introducción, vimos algunos ejemplos de programas de Python, para aquellos que nunca han programado antes.

Originalmente, sin embargo, Python estaba destinado a ser un lenguaje de script. Los lenguajes de secuencias de comandos tienen una sintaxis que los hace rápidos para escribir programas para el procesamiento de archivos y para realizar tareas repetitivas en una computadora.

Como ejemplo de una situación en la que Python es muy útil, imagine que su maestro ha realizado 5 cuestionarios durante todo el año y ha registrado los resultados para cada estudiante en un archivo como este (podría incluir más de 6 estudiantes), donde el nombre de cada estudiante es seguido por sus puntajes. Algunos estudiantes no se molestaron en ir a clase para todas las pruebas, por lo tanto, tienen menos de 5 resultados registrados.

Karen 12 12 14 18 17
James 9 7 1
Ben 19 17 19 13
Lisa 9 1 3 0
Amalia 20 20 19 15 18
Cameron 19 15 12 9 3

Ella se da cuenta de que necesita saber el promedio (suponiendo 5 pruebas) que calificó cada estudiante, y con muchas otras cosas que hacer no quiere pasar mucho tiempo en esta tarea. Con Python, puede generar rápidamente los datos que necesita en menos de 10 líneas de código.

Tenga en cuenta que comprender los detalles de este código es irrelevante para este capítulo, especialmente si aún no es un programador. Simplemente no lea los comentarios (las cosas que comienzan con un “#”) si no entiende, para que pueda tener una idea vaga de cómo se abordó el problema.

# Abra el archivo de puntuación sin procesar para leer
raw_scores_file = open (“score.txt”, “r”)
# Crear y abrir un archivo para escribir las puntuaciones procesadas en
created_scores_file = open (“shown_scores.txt”, “w”)

# Para cada línea en el archivo
para línea en raw_scores_file.readlines ():
# Obtenga el nombre, que está en la primera parte de la línea
nombre = line.split () [0]
# Obtenga una lista de los puntajes, que están en el resto de las líneas
score_on_line = [int (score) para puntaje en line.split () [1:]]
# Calcule el promedio, que es la suma de los puntajes dividido por 5
promedio = suma (puntajes_en_linea) / 5
# Escriba el promedio en el archivo de salida de puntajes procesados
process_scores_file.write (nombre + “” + str (promedio) + “\ n”)

# Cerrar ambos archivos
raw_scores_file.close ()
process_scores_file.close ()

Esto generará un archivo que contiene el nombre de cada estudiante seguido del resultado de agregar sus puntajes y dividir la suma entre 5. Puede probar el código si tiene instalado Python en su computadora (no funcionará en el intérprete en línea, porque necesita acceso a un sistema de archivos). Simplemente coloque los datos en bruto en un archivo llamado “score.txt” en el mismo formato que se mostró arriba. Siempre que esté en el mismo directorio que el archivo de código fuente que cree para el código, funcionará.

Este problema podría resolverse en cualquier idioma, pero algunos idiomas lo hacen mucho más simple que otros. Los lenguajes de ingeniería de software estándar como Java, de los que hablamos en breve, no ofrecen un procesamiento de archivos tan sencillo. Java requiere que el programador especifique qué hacer si falla la apertura del archivo para evitar que el programa se bloquee. Python no requiere que el programador haga esto, aunque tiene la opción de manejar la falla de apertura de archivos si el programador lo desea. Ambos enfoques tienen ventajas en diferentes situaciones. Para el maestro que escribe un guión rápido para procesar los resultados de la prueba, no importa si el programa falla, por lo que es ideal no perder el tiempo escribiendo código para tratarlo. Para un sistema de software grande que utilizan muchas personas, los bloqueos son inconvenientes y representan un riesgo para la seguridad. Obligar a todos los programadores que trabajan en ese sistema a manejar este posible bloqueo correctamente podría evitar muchos problemas más adelante, que es donde ayuda el enfoque de Java.

Además del manejo directo de archivos, Python no requirió que el código se pusiera dentro de una clase o función, y proporcionó algunas funciones integradas muy útiles para resolver el problema. Por ejemplo, la función que encontró la suma de la lista y la línea de código que pudo convertir la línea de texto sin formato en una lista de números (usando un patrón muy comúnmente usado).

Este mismo programa escrito en Java requeriría al menos el doble de líneas de código.

Hay muchos otros lenguajes de script además de Python, como Perl, Bash y Ruby.

3.2. Rasguño

Scratch es un lenguaje de programación utilizado para enseñar a las personas cómo programar. Se utiliza una interfaz de arrastrar y soltar para que los nuevos programadores no tengan que preocuparse tanto por la sintaxis, y los programas escritos en Scratch se centren en controlar personajes de dibujos animados u otros sprites en la pantalla.

Scratch nunca se usa en la programación en la industria, solo en la enseñanza. Si está interesado en probar Scratch, puede probarlo en línea aquí, sin necesidad de descargar ni instalar nada.

Este es un ejemplo de un programa simple en Scratch que es similar a los programas que tenemos arriba para Python y Java. Pide al usuario los números hasta que digan “detener” y luego encuentra el promedio de los números dados.

Y esta es la salida que se mostrará cuando se haga clic en la bandera verde:

Scratch se puede usar para cálculos simples, crear juegos y animaciones. Sin embargo, no tiene todas las capacidades de otros idiomas.

Otros idiomas educativos incluyen Alice y Logo. Alice también usa arrastrar y soltar, pero en un entorno 3D. Logo es un lenguaje de propósito general muy antiguo basado en Lisp. Ya no se usa mucho, pero era famoso por tener una tortuga con un bolígrafo que podía dibujar en la pantalla, al igual que Scratch. El diseño de Scratch estuvo parcialmente influenciado por Logo. Estos idiomas no se usan más allá de los propósitos educativos, ya que son lentos e ineficientes.

3.3. Java

Java es un lenguaje de ingeniería de software de uso general popular. Se utiliza para construir grandes sistemas de software que involucran posiblemente cientos o incluso miles de ingenieros de software. A diferencia de Python, obliga a los programadores a decir cómo se deben manejar ciertos errores, y los obliga a indicar qué tipo de datos están destinados a contener sus variables, por ejemplo, int (es decir, un número sin decimales) o String (algunos datos de texto ) Python no requiere que los tipos se establezcan de esta manera. Todas estas características ayudan a reducir la cantidad de errores en el código. Además, pueden hacer que sea más fácil para otros programadores leer el código, ya que pueden ver fácilmente qué tipo de variable se pretende que contenga (descubrir esto en un programa de Python escrito por otra persona puede ser un desafío a veces, lo que hace que sea muy difícil para modificar su código sin romperlo!)

Este es el código Java para resolver el mismo problema que analizamos en Python; generar un archivo de promedios.

import java.io. *;
import java.util. *;

Promedio de clase pública {
public static void main () {
String inputFile = “score.txt”;
String outputFile = “processing_scores.txt”;
tratar {
Escáner escáner = nuevo escáner (nuevo archivo (inputFile));
PrintStream outputFile = new PrintStream (nuevo archivo (outputFile));
while (scanner.hasNextLine ()) {
Nombre de cadena = scanner.next ();
Scanner numbersToRead = nuevo escáner (scanner.nextLine ());
int totalForLine = 0;
while (numbersToRead.hasNextInt ()) {
totalForLine + = numbersToRead.nextInt ();
}
outputFile.println (nombre + “” + totalForLine / 5.0 + “\ n”);
}
outputFile.close ();
} catch (IOException e) {
System.out.println (“¡No se pudo abrir el archivo!” + E);
}
System.out.println (“¡Ya terminé!”);
}
}

Si bien el código es más largo, garantiza que el programa no se bloquee si algo sale mal. Dice que intente abrir y leer el archivo, y si se produce un error, debe detectar ese error e imprimir un mensaje de error para informar al usuario. La alternativa (como en Python) sería simplemente bloquear el programa, evitando que cualquier otra cosa pueda ejecutarlo. Independientemente de si se produce o no un error, el mensaje “¡Ya terminé!” la línea se imprimirá porque el error se “capturó” de forma segura. Python puede hacer un manejo de errores como este, pero depende del programador hacerlo. ¡Java ni siquiera compilará el código si esto no se hizo! Esto evita que los programadores olviden o simplemente sean flojos.

Existen muchos otros lenguajes generales de ingeniería de software, como C # y C ++. Python a veces se usa para hacer grandes sistemas de software, aunque generalmente no se considera un lenguaje ideal para este rol.

3.4. JavaScript

  • Interpretado en un navegador web
  • Lenguaje similar: Actionscript (Flash)

Tenga en cuenta que esta sección se completará en una versión futura de la guía de campo. Por ahora, debe consultar la página de wikipedia para obtener más información.

3.5. C

  • Lenguaje de bajo nivel con la sintaxis de un lenguaje de alto nivel
  • Se utiliza comúnmente para programar sistemas operativos y sistemas integrados.
  • Los programas escritos en C tienden a ser muy rápidos (porque está diseñado de una manera que facilita su compilación óptima en código máquina)
  • Propenso a errores debido a los detalles de bajo nivel. Es mejor no usarlo en situaciones donde es innecesario
  • Lenguajes relacionados: C ++ (algo)

Tenga en cuenta que esta sección se completará en una versión futura de la guía de campo. Por ahora, debe consultar la página de wikipedia para obtener más información.

3.6. Matlab

  • Se usa para escribir programas que involucran matemáticas avanzadas (cálculo, álgebra lineal, etc.)
  • No disponible gratuitamente
  • Idiomas relacionados: Mathematica, Maple

Tenga en cuenta que esta sección se completará en una versión futura de la guía de campo. Por ahora, debe consultar la página de wikipedia para obtener más información.

3.7. Lenguajes de programación esotéricos

Cualquiera puede hacer su propio lenguaje de programación. Hacerlo implica crear una sintaxis para su idioma y escribir un analizador sintáctico y un compilador o un intérprete para poder ejecutar programas en su idioma. La mayoría de los lenguajes de programación que la gente ha creado nunca se utilizan ampliamente.

Además de los lenguajes de programación que tienen usos prácticos, las personas han creado muchos lenguajes de programación que no pretenden ser más que bromas, o para probar los límites de lo oscuro que puede ser un lenguaje de programación. ¡Algunos de ellos hacen que los lenguajes de máquina de bajo nivel que viste anteriormente parezcan bastante lógicos! Wikipedia tiene una lista de tales idiomas.

¡Incluso podría crear su propio lenguaje de programación si quisiera!

4. ¿Cómo procesa la computadora su programa?

Un lenguaje de programación como Python o Java se implementa utilizando un programa en sí mismo; ¡lo que toma y ejecuta su programa Python es un programa que alguien ha escrito!

Dado que el hardware de la computadora solo puede ejecutar programas en un lenguaje de bajo nivel (código de máquina), el sistema de programación debe permitir que sus instrucciones de Python se ejecuten usando solo lenguaje de máquina. Hay dos formas generales de hacer esto: interpretar y compilar.

Este video de 1983 ofrece una buena analogía de la diferencia entre un intérprete y un compilador.

La principal diferencia es que un compilador es un programa que convierte su programa a lenguaje de máquina, que luego se ejecuta en la computadora. Un intérprete es un programa que lee su programa línea por línea, calcula cuáles son esas instrucciones y las hace de inmediato.

Ambos enfoques tienen ventajas, y cada uno se adapta mejor a algunos idiomas que a otros. En realidad, la mayoría de los idiomas modernos usan una mezcla de compilación e interpretación. Por ejemplo, la mayoría de los programas Java se compilan en un “lenguaje intermedio” llamado ByteCode, que está más cerca del código de máquina que Java. ByteCode es ejecutado por un intérprete.

Si su programa se va a distribuir para un uso generalizado, generalmente querrá que esté en el código de la máquina porque se ejecutará más rápido, el usuario no tiene que tener un intérprete para su idioma en particular y cuando alguien descargue el código de la máquina , no reciben una copia de su programa original de alto nivel. Los lenguajes donde esto sucede incluyen C #, Objective C (utilizado para programar dispositivos iOS), Java y C.

Los programas interpretados tienen la ventaja de que pueden ser más fáciles de programar porque puede probarlos rápidamente, rastrear lo que está sucediendo en ellos más fácilmente e incluso a veces escribir instrucciones individuales para ver lo que hacen, sin tener que pasar por todo el proceso de compilación . Por esta razón, se usan ampliamente para los idiomas introductorios (por ejemplo, se interpretan Scratch y Alice), y también para programas simples como scripts que realizan tareas simples, ya que se pueden escribir y probar rápidamente (por ejemplo, lenguajes como PHP, Ruby y Python se usan en estas situaciones).

El siguiente diagrama muestra la diferencia entre lo que sucede en un intérprete y un compilador si escribe y ejecuta un programa que ordena algunos números. El compilador produce un programa de código de máquina que hará la clasificación, y los datos se introducen en ese segundo programa para obtener el resultado ordenado. El intérprete simplemente ordena la entrada siguiendo inmediatamente las instrucciones del programa. El compilador produce un programa de código de máquina que puede distribuir, pero implica una fase adicional en el proceso.

5. ¡Toda la historia!

Hay muchos lenguajes de programación diferentes, y siempre se inventan nuevos. Cada nuevo idioma necesitará un nuevo compilador y / o intérprete para ser desarrollado para soportarlo. Afortunadamente, existen buenas herramientas para ayudar a hacer esto rápidamente, y algunas de estas ideas aparecerán en el capítulo Idiomas formales , donde se pueden usar expresiones regulares y gramáticas para describir un lenguaje, y se puede construir un compilador automáticamente a partir de la descripción .

Los lenguajes que hemos discutido en este capítulo son los que probablemente encontrará en la programación introductoria, pero hay algunos estilos de lenguajes completamente diferentes que tienen aplicaciones muy importantes. Existe un enfoque de programación llamado programación funcional donde todas las operaciones se formulan como funciones matemáticas. Los lenguajes comunes que usan técnicas funcionales incluyen Lisp, Scheme, Haskell, Clojure y F #; Incluso algunos lenguajes convencionales (como Python) incluyen ideas de programación funcional. Un estilo de programación funcional puro elimina un problema llamado efectos secundarios , y sin este problema puede ser más fácil asegurarse de que un programa haga exactamente lo que está destinado a hacer. Otro tipo importante de programación es la programación lógica, donde un programa puede considerarse como un conjunto de reglas que establecen lo que debe hacer, en lugar de instrucciones sobre cómo hacerlo. El lenguaje de programación lógica más conocido es Prolog.

Todos los lenguajes de programación de alto nivel utilizados en la práctica eventualmente se reducen al código de la máquina, y el código de la máquina tiene una correspondencia aproximada con el lenguaje ensamblador, por lo que la respuesta es “sí” (en condiciones de que el problema no sea tan difícil que solo un compilador o similar programa puede hacerlo lo suficientemente rápido / bueno). También hay cosas fáciles de ensamblar que serían casi imposibles en la mayoría de los lenguajes de alto nivel.

El problema con el ensamblaje es que lleva mucho tiempo escribir código de ensamblaje limpio, legible y fácil de mantener. Quiero decir, piénsalo: es como si estuvieras en un idioma donde solo tienes de 5 a 6 variables globales (los registros de la CPU), con nombres ya predefinidos, y se supone que debes reutilizarlos para todo; no es que no pueda poner cosas en la memoria, pero generalmente se centrará en la asignación de registros. ¡Esto no fomenta exactamente las mejores prácticas de desarrollo de software! 😀

Entonces, felicitaciones a los programadores expertos de ensamblaje, pero para la mayoría de las personas, probablemente sea mejor apegarse a C (o superior) … al menos sé que no confío lo suficiente en mí mismo con el ensamblaje para sugerir que hagamos nuestro próximo proyecto. (Si hay una opción).

En algunos casos, sí, con una diferencia relativamente enorme en el esfuerzo puesto en desarrollo y prueba. En algunos casos no.

En qué casos son posibles:

En los casos en que las especificaciones completas del lenguaje ensamblador estén disponibles para todo el hardware subyacente. Pero, con el aumento en la complejidad de la tarea que estamos tratando de lograr, el tiempo requerido aumentará a un ritmo rápido y no mencionará la paciencia requerida durante el desarrollo.

Los lenguajes de alto nivel se crearon para hacer las cosas más fáciles y rápidas. Imagine al chef de un hotel en una cocina ultra moderna con todos los cortadores, batidoras, freidoras y herramientas de última generación. Esos son nuestros desarrolladores con lenguajes de alto nivel. El chef puede servir a más personas con menos tiempo y requiere mucho menos esfuerzo.

Ahora, ¿qué pasa si sacamos todos los electrodomésticos de cocina y le damos una configuración antigua con herramientas manuales, batidoras / trituradoras manuales y estufas de carbón? Sí, podrá cocinar la mayoría de las cosas que hizo con Modern Kitchen, pero Time and Effort será increíblemente alto. Este será el caso si el desarrollador está tratando de usar lenguaje ensamblador para desarrollo web y desarrollos de juegos.

No es posible cuando:

Si el fabricante del hardware no abre las especificaciones y las instrucciones de montaje, entonces no hay otra manera. Tomemos, por ejemplo, Apple, fuera de la compañía, tenemos que usar lenguajes de alto nivel para desarrollar (Objetivo C / Swift / etc …).

No de manera realista.

El recurso más valioso que tiene un programador es su tiempo. El lenguaje ensamblador es extremadamente detallado y requiere mucho más tiempo para resolver problemas que los lenguajes de nivel superior.

Supongamos que desea analizar un archivo access.log para ver qué solicitudes demoran más de 5 segundos. Puede obtener esta información en 5 minutos si usa awk. Le llevaría días a un programador experto hacerlo en lenguaje ensamblador. Durante esos días, el primer programador ya podría haber resuelto muchos más problemas.

Si levantó la restricción de tiempo y asume un tiempo infinito, entonces sí, cada programa se podría hacer en conjunto.

Por supuesto, en tres sencillos pasos.

Paso 1: construya un compilador simple en un lenguaje de alto nivel simple y bien diseñado, como Pascal

Paso 2: traduzca manualmente el compilador al lenguaje máquina

Paso 3: compila el programa en el lenguaje de alto nivel

Si y no.

Técnicamente hablando, es posible.

Hablando en términos prácticos, tomaría una cantidad absurda de tiempo, sería propenso a errores y sería terriblemente abrumador para el programador (incluso para un equipo de programadores).

Una analogía similar sería preguntar si un herrero experto (equipado con un cincel y un martillo) podría hacer la estatua de la libertad sin el uso de ningún equipo de construcción grande.