Una respuesta demasiado simplista es que el diseñador de la CPU lo especificó de esa manera. Cuando diseñamos el acelerador de expresión regular cave-creek, que tenía una pequeña “CPU” adentro, me senté y expuse qué patrones de bits causarían qué acciones. Eso esencialmente definió los códigos de operación de esa CPU. El diseño del conjunto de instrucciones puede ser una actividad muy divertida ya que tiene recursos limitados y está tratando de adivinar cómo usarlos de manera más efectiva.
Observe cómo hablé de una parte específica de un chip específico, cuando hablé de la CPU. Una computadora moderna, incluidas las de su teléfono, en realidad tiene muchos cpus, y no solo me refiero a muchos núcleos. A menudo hay pequeños cpus que realizan funciones especiales para su computadora que pueden o no ejecutarse todo el tiempo. La mayoría de los cuales nunca sabrás ni te importarán.
Por ejemplo, su unidad de disco puede tener un controlador de almacenamiento en caché, que puede incluir una CPU en miniatura especializada que decide qué direcciones almacenar en caché y qué direcciones descartar de la memoria caché. Es probable que esa CPU no tenga un código de operación en el sentido en que está pensando, pero aún ejecuta un programa que toma decisiones, y cuanto más complejo y sofisticado sea el controlador, más probable será que el programa sea configurable por software, y más cerca es probable que sea para algo que reconocería como una CPU y para tener un campo específico de “código de operación”.
- En la programación integrada, ¿qué hace 0X1 << 5, 1 | 2 << 4, 0x1 << 1 | 0x1 << 2 significa?
- ¿Qué es una plataforma integrada asequible para practicar la programación de firmware para protocolos de red inalámbrica?
- ¿Cuál es la información detallada de watchdog en el sistema integrado?
- ¿Cuál es la mejor fuente gratuita en línea para aprender sobre IoT y sistemas integrados?
- ¿Cómo debo acercarme a Linux (Linux para tontos)?
Del mismo modo, el último procesador cpus de Intel que conocía tenía al menos tres o cuatro CPU auxiliares que manejaban cosas como el arranque, la seguridad y las interrupciones. Uno de ellos era incluso un intérprete de Forth si no recuerdo mal. Muchos de esos cpus a los que no puedes acceder a menos que seas un oem. Incluso puede haber cpus en el interior que se usan solo mientras el chip se está fabricando y probando.
Ahora, hay una razón para todos estos “cpus”. Una vez que la lógica llega a un cierto nivel de complejidad, una forma fácil de razonar sobre ello es como una “máquina de estados”. Este es un modelo bien conocido que casi todos en ciencias de la computación o los campos relacionados se les enseña. Es la base de gran parte de la teoría de autómatas. De todos modos, a medida que las máquinas de estado se vuelven complejas, la evolución “natural” es hacia una “computadora de programa almacenada”, donde un poco de memoria retiene el programa y algún hardware ejecuta ese programa. La acción de “tecla” que realiza el hardware se denomina “operación” y los bits en la memoria que especifican esa acción se denominan “código de operación”.
Tenga en cuenta que no es necesario que el código de operación sea el “primer” byte (o incluso que sea un conjunto contiguo de bits, mucho menos un byte de longitud). Esas son solo convenciones que hacen que el conjunto de instrucciones de longitud variable de procesadores x86 sea fácil de implementar. Las máquinas que no están orientadas a bytes o que no tienen instrucciones de longitud variable no se limitan a esa organización y la mayoría de las veces usan otras formas de organizar los bits que no se ajustan a ese patrón.
Es común que el código de operación se especifique principalmente por un conjunto de bits que se agrupan lógicamente en un extremo de la memoria recuperada, simplemente porque eso hace que sea más fácil para el diseñador pensar en ellos. Sin embargo, si el conjunto de instrucciones surgió de algo más primitivo, o hay problemas con la longitud de los cables que conectan las partes, el código de operación se puede diseñar fácilmente a partir de piezas disjuntas, por ejemplo, los bits que especifican el direccionamiento indirecto a menudo se agrupan cerca de la dirección se están modificando para que esos bits se puedan enrutar juntos a la porción de memoria del chip y no tengan que ir a la “cpu” en absoluto. Del mismo modo, SIMD (datos múltiples de una sola instrucción) o MIMD (datos múltiples de varias instrucciones) o MISD cpus pueden dividir fácilmente el código de operación en diferentes partes.
Finalmente, los códigos de operación no se limitan solo a los cpus de hardware. Las máquinas virtuales pueden diseñarse siguiendo los mismos principios. Por ejemplo, en Yacc ++, el analizador generado es un programa para una computadora abstracta, y tiene códigos de operación y operandos, etc. Hay un software, “el motor” que ejecuta ese programa y al hacerlo implementa el analizador. Por lo tanto, también podemos implementar cpus en el software.
Ahora, como Alec señaló, cada uno de estos cpus solo ejecuta los códigos de operación a los que se dirige mediante el “contador de programa” (que puede o no ser una sola cosa) y si la CPU de alguna manera se dirige a bytes que no están destinados a sean instrucciones, la CPU puede hacer fácilmente algo inesperado. Dependiendo del diseño, puede ser posible recuperarse de eso o no. Afortunadamente, la mayoría de los diseñadores ponen operaciones de tipo a prueba de fallas en el diseño para que haya una manera de volver a un estado conocido. El pequeño botón de reinicio al que necesita un clip para llegar, esa es una de esas cosas. Si “bloquea” su dispositivo, lo ha puesto en un estado del que no sabe (o quizás nadie lo sabe) cómo recuperarse. La necesidad frecuente de reiniciar Windows fue un artefacto de lo mismo: el reinicio devolvió el sistema operativo (una CPU muy grande, compleja y poco entendida) a un estado conocido.