La estructura de comando del lenguaje ensamblador contiene: Estructura de comandos en programación a nivel de lenguaje ensamblador. Formato de datos y estructura de comando del lenguaje ensamblador.

Comandos en lenguaje ensamblador (Conferencia)

PLAN DE CONFERENCIA

1. Principales grupos de operaciones.

Pentium.

1. Principales grupos de operaciones

Los microprocesadores ejecutan un conjunto de comandos que implementan los siguientes grupos principales de operaciones:

Operaciones de reenvío

Operaciones aritmeticas,

Operaciones lógicas

Operaciones de turno

Operaciones de comparación y prueba.

Operaciones de bits

Operaciones de gestión de programas;

Operaciones de control del procesador.

2. Códigos mnemotécnicos de comandos del procesador. Pentium

Al describir comandos, generalmente se utilizan sus designaciones mnemotécnicas (códigos mnemotécnicos), que se utilizan para especificar el comando cuando se programa en lenguaje ensamblador. Para diferentes versiones de Assembler, los códigos mnemotécnicos de algunos comandos pueden diferir. Por ejemplo, para que el comando llame a una subrutina, se utiliza el código mnemotécnicoLLAMAR o jsr ("Salta a Subrutina"). Sin embargo, los códigos mnemotécnicos para la mayoría de los comandos de los principales tipos de microprocesadores son iguales o difieren ligeramente, ya que son abreviaturas de las palabras inglesas correspondientes que definen la operación que se está realizando. Veamos los códigos mnemotécnicos de comando adoptados para los procesadores. Pentium.

Comandos de reenvío. El equipo principal de este grupo es el equipo.MOVIMIENTO , que proporciona transferencia de datos entre dos registros o entre un registro y una celda de memoria. Algunos microprocesadores implementan transferencias entre dos celdas de memoria, así como transferencias masivas del contenido de varios registros de la memoria. Por ejemplo, microprocesadores de la familia 68. motorola xxx ejecutar el comandoMOVER , proporcionando transferencia de una celda de memoria a otra, y el comandoMOVEM , que escribe en la memoria o carga desde la memoria el contenido de un conjunto específico de registros (hasta 16 registros). EquipoXCHG intercambia mutuamente el contenido de dos registros del procesador o un registro y una celda de memoria.

Comandos de entrada EN y salida AFUERA implementar el envío de datos desde un registro de procesador a un dispositivo externo o la recepción de datos desde un dispositivo externo a un registro. Estos comandos especifican el número del dispositivo de interfaz (puerto de entrada/salida) a través del cual se transfieren los datos. Tenga en cuenta que muchos microprocesadores no tienen comandos especiales para acceder a dispositivos externos. En este caso, la entrada y salida de datos en el sistema se realiza mediante el comandoMOVIMIENTO , que especifica la dirección del dispositivo de interfaz requerido. Por lo tanto, el dispositivo externo se direcciona como una celda de memoria y en el espacio de direcciones se asigna una determinada sección en la que se encuentran las direcciones de los dispositivos de interfaz (puertos) conectados al sistema.

Comandos de operaciones aritméticas. Los comandos principales de este grupo son la suma, la resta, la multiplicación y la división, que tienen varias opciones. Comandos de suma AGREGAR y resta SUB realizar las operaciones correspondientes conCposeído por dos registros, un registro y una ubicación de memoria, o utilizando un operando inmediato. equipos ANUNCIO C , S.B. B realizar sumas y restas teniendo en cuenta el valor del atributoC, establecido al formar una transferencia durante la ejecución de la operación anterior. Con estos comandos, se implementa la suma secuencial de operandos, cuyo número de bits excede la capacidad del procesador. Equipo N.E.G. cambia el signo del operando, convirtiéndolo en complemento a dos.

Las operaciones de multiplicación y división se pueden realizar en números con signo (comandosI MUL, I DIV ) o sin firmar (comandos MUL, DIV ) Uno de los operandos siempre está ubicado en un registro, el segundo puede estar en un registro, en una celda de memoria o ser un operando inmediato. El resultado de la operación se ubica en el registro. Al multiplicar (comandosMUL , IMUL ) el resultado es de doble bit, para lo cual se utilizan dos registros. Al dividir (comandosDIV , IDIV ) como dividendo, se utiliza un operando de doble bit, colocado en dos registros y, como resultado, el cociente y el resto se escriben en dos registros.

Comandos de operación lógica . Casi todos los microprocesadores realizan operaciones lógicas Y, O, O exclusivo, que se realizan en los mismos bits de operandos mediante comandos. Y, O, X O . Las operaciones se realizan sobre el contenido de dos registros, un registro y una ubicación de memoria, o utilizando un operando inmediato. Equipo NO invierte el valor de cada bit del operando.

Comandos de cambio. Los microprocesadores realizan cambios aritméticos, lógicos y cíclicos de operandos direccionados en uno o más bits. El operando que se va a desplazar puede estar en un registro o en una ubicación de memoria, y el número de bits de desplazamiento está especificado por el operando inmediato contenido en la instrucción o determinado por el contenido del registro especificado. La señal de transferencia suele estar involucrada en la implementación del cambio.Cen el registro de estado (S.R. o EFLAGS), que contiene el último bit del operando eliminado del registro o celda de memoria.

Comandos de comparación y prueba. . La comparación de operandos generalmente se realiza usando el comandoCMP , que resta operandos y establece valores de características norte, z, v, c en el registro de estado según el resultado obtenido. En este caso, el resultado de la resta no se guarda y los valores de los operandos no cambian. El análisis posterior de los valores de características obtenidos nos permite determinar el valor relativo (>,<, =) операндов со знаком или без знака. Использование различных способов адресации позволяет производит сравнение содержимого двух регистров, регистра и ячейки памяти, непосредственно заданного операнда с содержимым регистра или ячейки памяти.

Algunos microprocesadores ejecutan el comando de prueba. TST , que es una versión de un solo operando de la instrucción de comparación. Cuando se ejecuta este comando, los signos se configuran. norte, z según el signo y valor (igual o distinto de cero) del operando direccionado.

Instrucciones de operación de bits . Estos comandos establecen el valor del atributo.Cen el registro de estado de acuerdo con el valor del bit que se está probandomn en el operando direccionado. En algunos microprocesadores, según el resultado de las pruebas de bits, se establece el atributoz. Número de bit de pruebanortese especifica por el contenido del registro especificado en el comando o por el operando inmediato.

Los comandos de este grupo implementan diferentes opciones para cambiar el bit que se está probando. BT mantiene el valor de este bit sin cambios.Comando B t S la prueba posterior establece el valor mn=1, y el comando B t C - significado mn=0.Equipo B t C invierte el valor del bit bn después de probarlo.

Operaciones de gestión de programas. Para controlar el programa se utiliza una gran cantidad de comandos, entre los que se encuentran:

- comandos de transferencia de control incondicional;

- comandos de salto condicionales;

- equipos para organizar ciclos de programas;

- interrumpir comandos;

- Comandos para cambiar atributos.

La transferencia incondicional de control se realiza mediante el comando.JMP , que se carga en el contador del programa.ordenador personalnuevo contenido que es la dirección del siguiente comando a ejecutar. Esta dirección se especifica directamente en el comandoJMP (direccionamiento directo), o calculado como la suma de los contenidos actualesordenador personaly el desplazamiento especificado en el comando, que es un número con signo (direccionamiento relativo). Porqueordenador personalcontiene la dirección del siguiente comando del programa, el último método especifica la dirección de salto, desplazada con respecto a la siguiente dirección en un número específico de bytes. Con un desplazamiento positivo, la transición se realiza a los comandos posteriores del programa, con un desplazamiento negativo, a los anteriores.

Una subrutina también se llama transfiriendo el control incondicionalmente usando el comandoLLAMAR (o jsr ). Sin embargo, en este caso, antes de cargar enordenador personal nuevo contenido que especifica la dirección del primer comando de la subrutina, es necesario guardar su valor actual (la dirección del siguiente comando) para garantizar un retorno al programa principal después de la ejecución de la subrutina (o al anterior subrutina al anidar subrutinas). Los comandos de salto condicional (ramas del programa) se cargan enordenador personalcontenido nuevo si se cumplen ciertas condiciones, que generalmente se establecen de acuerdo con el valor actual de varios atributos en el registro de estado. Si no se cumple la condición, se ejecuta el siguiente comando del programa.

Los comandos de control de funciones permiten escribir: leer el contenido del registro de estado en el que se almacenan las funciones, así como cambiar los valores de las funciones individuales. Por ejemplo, los procesadores Pentium implementan los comandos LAHF Y SAHF , que cargan el byte bajo, que contiene los signos, desde el registro de estado EFLAG al byte bajo del registro EAX y rellenando el byte bajo EFLAGS del registro E AX.. equipos CVX, STC lleve a cabo la configuración de los valores del signo de transferencia CF=0, CF=1 y el comando CMC hace que el valor de este atributo se invierta. Dado que los atributos determinan el flujo de ejecución del programa durante las transiciones condicionales, los comandos de cambio de atributos generalmente se usan para controlar el programa.

Comandos de control del procesador . Este grupo incluye comandos de parada, comandos de no operación y una serie de comandos que determinan el modo de funcionamiento del procesador o sus bloques individuales. EquipoHLT detiene la ejecución del programa y pone el procesador en un estado de parada, del cual se sale cuando se recibe una señal de interrupción o reinicio ( Reiniciar ). Equipo NOP (comando "vacío"), que no provoca que se realice ninguna operación, se utiliza para implementar retrasos en el programa o llenar los vacíos formados en el programa.

equipos especiales ICL, ITS prohibir y permitir el servicio de solicitudes de interrupción. en procesadores Pentium para esto se utiliza un bit de control (bandera)SI en el registro EFLAGS.

Muchos microprocesadores modernos emiten un comando de identificación que permite al usuario u otros dispositivos obtener información sobre el tipo de procesador utilizado en un sistema determinado. en procesadores Pentuim el comando para esto es ID de CPU , durante el cual los datos necesarios sobre el procesador ingresan a los registros EAXEBXECXEDX y luego puede ser leído por el usuario o el sistema operativo.

Dependiendo de los modos de funcionamiento implementados por el procesador y de los tipos específicos de datos que se procesan, el conjunto de comandos ejecutados se puede ampliar significativamente.

Algunos procesadores realizan operaciones aritméticas con números binario-decimales o ejecutan instrucciones especiales para corregir el resultado al procesar dichos números. Muchos procesadores de alto rendimiento incluyen FPU - unidad de procesamiento de números C "punto flotante".

Varios procesadores modernos implementan el procesamiento grupal de varios números enteros o números. C “punto flotante” usando un comando según el principio SIMD (“Instrucción única – Datos múltiples” ”) - “Un comando – Muchos datos”. La ejecución simultánea de operaciones en múltiples operandos mejora significativamente el rendimiento del procesador cuando se trabaja con datos de video y audio. Estas operaciones se utilizan ampliamente para procesar imágenes, señales de audio y otras aplicaciones. Para realizar estas operaciones se han introducido en los procesadores bloques especiales que implementan los correspondientes conjuntos de instrucciones, que en varios tipos de procesadores ( pentio, atlón) obtuvo el nombremmx (“ miltí- Extensión de medios ”) – Extensión multimedia,ESS(“Extensión de transmisión SIMD”) – Transmisión SIMD - extensión, “3 DExtensión– Expansión tridimensional.

Un rasgo característico de los procesadores de la empresa. Intel , comenzando con el modelo 80286, es el control de prioridad al acceder a la memoria, que se proporciona cuando el procesador opera en modo de direcciones virtuales protegidas - " Modo protegido " (modo protegido). Para implementar este modo, se utilizan grupos especiales de comandos, que sirven para organizar la protección de la memoria de acuerdo con el algoritmo de acceso prioritario adoptado.

Estructura de comandos en lenguaje ensamblador La programación a nivel de comandos de máquina es el nivel mínimo en el que es posible la programación informática. El sistema de comando de la máquina debe ser suficiente para implementar las acciones requeridas mediante la emisión de instrucciones al equipo de la máquina. Cada instrucción de máquina consta de dos partes: una operativa, que determina “qué hacer” y un operando, que determina los objetos de procesamiento, es decir, “qué hacer”. Una instrucción de máquina con microprocesador, escrita en lenguaje ensamblador, es una sola línea que tiene la siguiente forma: etiqueta comando/directiva operando(s); comentarios La etiqueta, el comando/directiva y el operando están separados por al menos un espacio o carácter de tabulación. Los operandos del comando están separados por comas.

Estructura de comandos en lenguaje ensamblador Un comando en ensamblador le dice al traductor qué acción debe realizar el microprocesador. Las directivas de ensamblaje son parámetros especificados en el texto del programa que afectan el proceso de ensamblaje o las propiedades del archivo de salida. El operando especifica el valor inicial de los datos (en el segmento de datos) o los elementos sobre los cuales se realiza la acción del comando (en el segmento de código). Una instrucción puede tener uno o dos operandos, o ningún operando. El número de operandos está especificado implícitamente en el código de instrucción. Si es necesario continuar con un comando o directiva en la siguiente línea, se utiliza el carácter de barra invertida: "" . De forma predeterminada, el ensamblador no distingue entre letras mayúsculas y minúsculas al escribir comandos y directivas. Ejemplos de directivas y comandos Count db 1 ; Nombre, directiva, un operando mov eax, 0; Comando, dos operandos

Los identificadores son secuencias de caracteres válidos que se utilizan para indicar nombres de variables y nombres de etiquetas. El identificador puede constar de uno o más de los siguientes caracteres: todas las letras del alfabeto latino; números del 0 al 9; caracteres especiales: _, @, $, ? . Se puede utilizar un punto como primer carácter de la etiqueta. Los nombres de ensamblador reservados (directivas, operadores, nombres de comandos) no se pueden utilizar como identificadores. El primer carácter del identificador debe ser una letra o un carácter especial. Longitud máxima El identificador tiene 255 caracteres, pero el traductor acepta los primeros 32 e ignora el resto. Todas las etiquetas escritas en una línea que no contenga una directiva de ensamblador deben terminar con dos puntos ":". La etiqueta, el comando (directiva) y el operando no tienen que comenzar en ninguna posición particular de la línea. Se recomienda escribirlos en una columna para una mayor legibilidad del programa.

Etiquetas Todas las etiquetas escritas en una línea que no contiene una directiva de ensamblador deben terminar con dos puntos ":". La etiqueta, el comando (directiva) y el operando no tienen que comenzar en ninguna posición particular de la línea. Se recomienda escribirlos en una columna para una mayor legibilidad del programa.

Comentarios El uso de comentarios en un programa mejora su claridad, especialmente cuando el propósito de un conjunto de comandos no está claro. Los comentarios comienzan en cualquier línea del módulo fuente con un punto y coma (;). Todos los caracteres a la derecha de "; " al final de la línea hay un comentario. Un comentario puede contener cualquier carácter imprimible, incluido el espacio. Un comentario puede abarcar toda la línea o seguir un comando en la misma línea.

Estructura del programa en lenguaje ensamblador Un programa escrito en lenguaje ensamblador puede constar de varias partes llamadas módulos, cada una de las cuales puede definir uno o más segmentos de datos, pila y código. Cualquier programa completo en lenguaje ensamblador debe incluir un módulo principal, o principal, desde el cual comienza su ejecución. Un módulo puede contener segmentos de programa, datos y pila, declarados mediante directivas apropiadas.

Modelos de memoria Antes de declarar segmentos, debe especificar el modelo de memoria mediante una directiva. Modificador MODELO modelo_memoria, convención_llamada, tipo_OS, parámetro_pila Modelos de memoria en lenguaje ensamblador básico: Modelo de memoria Direccionamiento de código Direccionamiento de datos Sistema operativo Intercalado de código y datos PEQUEÑO CERCA DE MS-DOS Aceptable PEQUEÑO CERCA DE MS-DOS, Windows No MEDIO LEJOS CERCA DE MS-DOS, Windows No COMPACTO CERCA DE LEJOS MS-DOS, Windows No GRANDE LEJOS MS-DOS, Windows No ENORME LEJOS MS-DOS, Windows No CERCA de Windows 2000, Windows XP, Windows Aceptable PLANO CERCA DE NT,

Modelos de memoria El modelo pequeño sólo funciona en aplicaciones MS-DOS de 16 bits. En este modelo, todos los datos y códigos se encuentran en un segmento físico. El tamaño del archivo del programa en este caso no supera los 64 KB. El modelo pequeño admite un segmento de código y un segmento de datos. Los datos y el código se abordan lo más cerca posible cuando se utiliza este modelo. El modelo mediano admite múltiples segmentos de código y un segmento de datos, donde todas las referencias en segmentos de código se consideran lejanas de forma predeterminada y las referencias en un segmento de datos se consideran cercanas. El modelo compacto admite varios segmentos de datos que utilizan direccionamiento de datos lejanos (lejos) y un segmento de código que utiliza direccionamiento cercano (cerca). El modelo grande admite múltiples segmentos de código y múltiples segmentos de datos. De forma predeterminada, todas las referencias a código y datos se consideran lejanas. El modelo enorme es casi equivalente al modelo de memoria grande.

Modelos de memoria El modelo plano asume una configuración de programa no segmentado y se utiliza sólo en sistemas operativos de 32 bits. Este modelo es similar al modelo pequeño en que los datos y el código están ubicados en un solo segmento, pero es de 32 bits. Desarrollar un programa para el modelo plano ante la directiva. El modelo de piso debe colocar una de las directivas: . 386, . 486, . 586 o. 686. La elección de la directiva de selección del procesador determina el conjunto de instrucciones disponibles al escribir programas. La letra p después de la directiva de selección del procesador significa modo de funcionamiento protegido. El direccionamiento de datos y códigos está cerca, y todas las direcciones y punteros son de 32 bits.

Modelos de memoria. Modificador MODEL modelo_memoria, convención_llamada, tipo_OS, parámetro_pila El parámetro modificador se usa para definir tipos de segmentos y puede tomar los siguientes valores: use 16 (los segmentos del modelo seleccionado se usan como 16 bits) use 32 (se usan los segmentos del modelo seleccionado como 32 bits). El parámetro call_convention se utiliza para determinar el método para pasar parámetros al llamar a un procedimiento desde otros lenguajes, incluidos los lenguajes de alto nivel (C++, Pascal). El parámetro puede tomar los siguientes valores: C, BASIC, FORTRAN, PASCAL, SYSCALL, STDCALL.

Modelos de memoria. Modificador MODEL modelo_memoria, convención_llamada, tipo_OS, parámetro_pila El parámetro tipo_OS es OS_DOS de forma predeterminada y actualmente es el único valor admitido para este parámetro. El parámetro stack_parameter se establece en: NEARSTACK (el registro SS es igual a DS, los datos y las áreas de pila están ubicados en el mismo segmento físico) FARSTACK (el registro SS no es igual a DS, los datos y las áreas de pila están ubicados en diferentes segmentos físicos). El valor predeterminado es NEARSTACK.

Un ejemplo de un programa que no hace nada. 686 P. MODELO PLANO, STDCALL. DATOS. CODIGO INICIO: RET FIN INICIO RET - comando del microprocesador. Garantiza que el programa finalice correctamente. El resto del programa se refiere al funcionamiento del traductor. . 686 P: se permiten comandos en modo protegido de Pentium 6 (Pentium II). Esta directiva selecciona el conjunto admitido de instrucciones de ensamblador, indicando el modelo del procesador. . MODELO PLANO, stdcall - modelo de memoria plana. Este modelo de memoria se utiliza en el quirófano. sistema windows. stdcall: la convención de llamada al procedimiento utilizada.

Un ejemplo de un programa que no hace nada. 686 P. MODELO PLANO, STDCALL. DATOS. CÓDIGO INICIO: RET FIN INICIO. DATOS es un segmento de programa que contiene datos. Este programa no utiliza la pila, por lo que el segmento. Falta la PILA. . CÓDIGO es un segmento de programa que contiene código. INICIO - etiqueta. END START: el final del programa y un mensaje al compilador de que la ejecución del programa debe comenzar con la etiqueta START. Cada programa debe contener una directiva END para marcar el final. código fuente programas. Todas las líneas que siguen a la directiva END se ignoran. La etiqueta especificada después de la directiva END le dice al traductor el nombre del módulo principal desde el cual comienza la ejecución del programa. Si el programa contiene un módulo, se puede omitir la etiqueta después de la directiva END.

Traductores de lenguaje ensamblador Un traductor es un programa o herramienta técnica que convierte un programa presentado en uno de los lenguajes de programación en un programa en el lenguaje de destino, llamado código objeto. Además de admitir mnemónicos de instrucción automática, cada traductor tiene su propio conjunto de directivas y macroherramientas, a menudo incompatibles con cualquier otra cosa. Los principales tipos de traductores de lenguaje ensamblador: MASM (Microsoft Assembler), TASM (Borland Turbo Assembler), FASM (Flat Assembler), un ensamblador multipaso de distribución gratuita escrito por Tomasz Gryshtar (polaco), NASM (Netwide Assembler), un programa gratuito. ensamblador para la arquitectura Intel x 86, fue creado por Simon Tatham con Julian Hall y actualmente está siendo desarrollado por un pequeño equipo de desarrolladores en Source. Fragua. neto.

Src="https://present5.com/presentation/-29367016_63610977/image-15.jpg" alt="Traducir un programa en Microsoft Visual Studio 2005 1) Cree un proyecto seleccionando Archivo->Nuevo- >Menú Proyecto Y"> Трансляция программы в Microsoft Visual Studio 2005 1) Создать проект, выбрав меню File->New->Project и указав имя проекта (hello. prj) и тип проекта: Win 32 Project. В дополнительных опциях мастера проекта указать “Empty Project”.!}

Src="https://present5.com/presentation/-29367016_63610977/image-16.jpg" alt="Traducir el programa en Microsoft Visual Studio 2005 2) En el árbol del proyecto (Ver->Explorador de soluciones) agregar"> Трансляция программы в Microsoft Visual Studio 2005 2) В дереве проекта (View->Solution Explorer) добавить файл, в котором будет содержаться текст программы: Source. Files->Add->New. Item.!}

Traducir el programa a Microsoft Visual Studio 2005 3) Seleccione el tipo de archivo Código C++, pero especifique el nombre con la extensión. conjunto:

Traducir el programa a Microsoft Visual Studio 2005 5) Establecer los parámetros del compilador. Haga clic derecho en el menú Reglas de compilación personalizadas en el archivo del proyecto...

Traduzca el programa a Microsoft Visual Studio 2005 y seleccione Microsoft Macro Assembler en la ventana que aparece.

Traducción del programa en Microsoft Visual Studio 2005 Consulta con el botón derecho en el archivo hola. asm del árbol de proyectos del menú Propiedades e instale General->Herramienta: Microsoft Macro Assembler.

Src="https://present5.com/presentation/-29367016_63610977/image-22.jpg" alt="Traducción del programa en Microsoft Visual Studio 2005 6) Compile el archivo seleccionando Build->Build hello. prj."> Трансляция программы в Microsoft Visual Studio 2005 6) Откомпилировать файл, выбрав Build->Build hello. prj. 7) Запустить программу, нажав F 5 или выбрав меню Debug->Start Debugging.!}

Programación en el sistema operativo Windows La programación en el sistema operativo Windows se basa en el uso de funciones API (interfaz de programa de aplicación, es decir, interfaz de aplicación de software). Su número llega a 2000. El programa de Windows se compone en gran medida de este tipo de llamadas. Todas las interacciones con dispositivos externos y los recursos del sistema operativo se producen, por regla general, a través de dichas funciones. El sistema operativo Windows utiliza un modelo de memoria plana. La dirección de cualquier celda de memoria estará determinada por el contenido de un registro de 32 bits. Hay 3 tipos de estructuras de programas para Windows: diálogo (la ventana principal es diálogo), consola o estructura sin ventanas, estructura clásica (ventana, marco).

Llamar Funciones de Windows API En el archivo de ayuda, cualquier función API se presenta como tipo nombre_función (FA 1, FA 2, FA 3) Tipo: tipo de valor de retorno; FAx: una lista de argumentos formales en el orden en que aparecen. Por ejemplo, int Message. Box(HWND h. Wnd, LPCTSTR lp. Texto, LPCTSTR lp. Título, UINT u. Tipo); Esta función muestra una ventana con un mensaje y un botón (o botones) de salida. Significado de los parámetros: h. Wnd es un descriptor de la ventana en la que aparecerá la ventana del mensaje, lp. Texto: texto que aparecerá en la ventana, lp. Título: texto en el título de la ventana, u. Tipo: tipo de ventana; en particular, puede determinar el número de botones de salida.

Llamar a las funciones de mensaje int de la API de Windows. Box(HWND h. Wnd, LPCTSTR lp. Texto, LPCTSTR lp. Título, UINT u. Tipo); Casi todos los parámetros de las funciones API son en realidad enteros de 32 bits: HWND es un entero de 32 bits, LPCTSTR es un puntero a una cadena de 32 bits y UINT es un entero de 32 bits. El sufijo "A" a menudo se agrega al nombre de la función para pasar a versiones más nuevas de la función.

Llamar a las funciones de mensaje int de la API de Windows. Box(HWND h. Wnd, LPCTSTR lp. Texto, LPCTSTR lp. Título, UINT u. Tipo); Cuando use MASM, debe agregar @N N al final del nombre: la cantidad de bytes que ocupan los argumentos pasados ​​​​en la pila. Para las funciones API de Win 32, este número se puede definir como el número de argumentos n multiplicado por 4 (bytes en cada argumento): N=4*n. Para llamar a una función, utilice la instrucción CALL del ensamblador. En este caso, todos los argumentos de la función se le pasan a través de la pila (comando PUSH). Dirección de paso de argumentos: DE IZQUIERDA A DERECHA - DE ABAJO ARRIBA. El argumento u se colocará primero en la pila. Tipo. La llamada a la función especificada se verá así: CALL Message. Caja. @16

Llamar a las funciones de mensaje int de la API de Windows. Box(HWND h. Wnd, LPCTSTR lp. Texto, LPCTSTR lp. Título, UINT u. Tipo); El resultado de ejecutar cualquier función API suele ser un número entero que se devuelve en el registro EAX. La directiva OFFSET representa un "desplazamiento en un segmento" o, traducido a términos de lenguaje de alto nivel, un "puntero" al comienzo de una línea. La directiva EQU, como #define en SI, define una constante. La directiva EXTERN le dice al traductor que la función o identificador es externo a este módulo.

Ejemplo de un programa “¡Hola a todos!” . 686 P. MODELO PLANO, STDCALL. STACK 4096. DATA MB_OK EQU 0 STR 1 DB "Mi primer programa", 0 STR 2 DB "¡Hola a todos!", 0 HW DD ? Mensaje EXTERNO. Caja. A@16: CERCA. CODIGO INICIO: PUSH MB_OK PUSH OFFSET STR 1 PUSH OFFSET STR 2 PUSH HW CALL Mensaje. Caja. A@16 RET FIN INICIO

La directiva INVOKE El traductor de lenguaje MASM también le permite simplificar las llamadas a funciones usando una herramienta macro: la directiva INVOKE: función INVOKE, parámetro1, parámetro2, ... No es necesario agregar @16 a la llamada a la función; Los parámetros se escriben exactamente en el orden en que se proporcionan en la descripción de la función. Mediante macro mediante el traductor, los parámetros se colocan en la pila. Para utilizar la directiva INVOKE, debe tener una descripción del prototipo de función utilizando la directiva PROTO en el formato: Mensaje. Caja. A PROTO: DWORD, : DWORD Si un programa utiliza muchas funciones API de Win 32, es recomendable utilizar la directiva de inclusión C: masm 32includeuser 32. inc

Estructuras en lenguaje ensamblador

Las matrices que consideramos anteriormente son una colección de elementos del mismo tipo. Pero a menudo en las aplicaciones es necesario considerar un determinado conjunto de datos. diferentes tipos como un solo tipo.

Esto es muy importante, por ejemplo, para programas de bases de datos, donde es necesario asociar una colección de datos de diferentes tipos con un objeto.

Por ejemplo, anteriormente analizamos el Listado 4, en el que trabajamos con una matriz de elementos de tres bytes. Cada elemento, a su vez, constaba de dos elementos de diferentes tipos: un campo contador de un byte y un campo de dos bytes, que podía contener alguna otra información necesaria para el almacenamiento y procesamiento. Si el lector está familiarizado con uno de los lenguajes de alto nivel, entonces sabrá que dicho objeto generalmente se describe utilizando un tipo de datos especial: estructuras.

Para mejorar la usabilidad del lenguaje ensamblador, también se introdujo este tipo de datos.

priorato estructura Es un tipo de datos que consta de un número fijo de elementos de diferentes tipos.

Para utilizar estructuras en un programa, debes realizar tres pasos:

    Colocar plantilla de estructura .

    Básicamente, esto significa definir un nuevo tipo de datos, que posteriormente se puede utilizar para definir variables de este tipo.

    Definir instancia de estructura .

    Esta etapa implica inicializar una variable específica con una estructura predefinida (usando plantilla).

    Organizar acceder a elementos de estructura .

Es muy importante que entiendas desde el principio cuál es la diferencia entre descripción estructuras en el programa y sus definición.

Describir estructura en un programa simplemente significa indicar su esquema o patrón; la memoria no está asignada.

Esta plantilla sólo puede considerarse como información para el traductor sobre la ubicación de los campos y su valor predeterminado.

Definir estructura significa ordenar al traductor que asigne memoria y asigne un nombre simbólico a esta área de memoria.

Una estructura se puede describir en un programa sólo una vez, pero se puede definir cualquier número de veces.

Descripción de la plantilla de estructura.

La descripción de la plantilla de estructura tiene la siguiente sintaxis:

nombre_estructura STRUC

nombre_estructura TERMINA

Aquí es una secuencia de directivas de descripción de datos db, dw, dd, dq Y dt.

Sus operandos determinan el tamaño de los campos y, si es necesario, los valores iniciales. Estos valores probablemente inicializarán los campos correspondientes al definir la estructura.

Como ya señalamos al describir la plantilla, no se asigna memoria, ya que es solo información para el traductor.

Ubicación La plantilla en el programa puede ser arbitraria, pero, siguiendo la lógica del traductor de un solo paso, debe ubicarse antes del lugar donde se define la variable con el tipo de estructura dada. Es decir, al describir una variable con el tipo de una determinada estructura en un segmento de datos, su plantilla debe colocarse al principio del segmento de datos o antes de él.

Consideremos trabajar con estructuras usando el ejemplo de modelar una base de datos sobre los empleados de un determinado departamento.

Por simplicidad, para evitar problemas de conversión de información al ingresar, aceptaremos que todos los campos sean campos de caracteres.

Definamos la estructura de registros de esta base de datos con la siguiente plantilla:

Definición de datos con tipo de estructura.

Para utilizar una estructura descrita mediante una plantilla en un programa, debe definir una variable con el tipo de esta estructura. Para ello se utiliza la siguiente construcción sintáctica:

[nombre de la variable] nombre_estructura

    nombre de la variable- identificador de una variable de este tipo de estructura.

    Especificar un nombre de variable es opcional. Si no lo especifica, un área de memoria de tamaño igual a la suma de las longitudes de todos elementos de estructura.

    lista de valores- una lista de valores iniciales de elementos estructurales entre corchetes angulares, separados por comas.

    Su asignación también es opcional.

    Si la lista no está completamente especificada, todos los campos de la estructura para esta variable se inicializan con valores de la plantilla, si se especifica alguno.

    Es posible inicializar campos individuales, pero en este caso los campos que faltan deben estar separados por comas. Los campos omitidos se inicializarán con los valores de la plantilla de estructura. Si al definir una nueva variable con el tipo de una estructura determinada, estamos de acuerdo con todos los valores de campo en su plantilla (es decir, los especificados por defecto), entonces solo necesitamos escribir corchetes angulares.

    P.ej: trabajador victorioso.

Por ejemplo, definamos varias variables con el tipo de estructura descrita anteriormente.

Métodos para trabajar con estructura.

La idea de introducir un tipo estructurado en cualquier lenguaje de programación es combinar variables de diferentes tipos en un solo objeto.

El lenguaje debe tener un medio para acceder a estas variables dentro de una instancia específica de la estructura. Para hacer referencia a un campo de alguna estructura en un comando, se utiliza un operador especial: símbolo ". " (punto). Se utiliza en la siguiente sintaxis:

    expresión_dirección- identificador de una variable de algún tipo estructural o expresión entre paréntesis de acuerdo con las reglas sintácticas que se indican a continuación (Fig. 1);

    nombre_campo_estructura- nombre del campo de la plantilla de estructura.

    Esto, de hecho, también es una dirección, o más bien, el desplazamiento del campo desde el comienzo de la estructura.

Así el operador " . " (punto) evalúa la expresión

Arroz. 5. Sintaxis de una expresión de dirección en un operador de acceso a campo de estructura

Demostrémoslo usando el ejemplo de la estructura que hemos definido. obrero Algunas técnicas para trabajar con estructuras.

Por ejemplo, extraer a hacha valores de campo con edad. Dado que es poco probable que la edad de una persona trabajadora sea superior a 99 años, después de colocar el contenido de este campo de carácter en el registro hacha Será conveniente convertirlo a representación binaria con el comando anuncio.

Tenga cuidado porque debido al principio de almacenamiento de datos “byte bajo en dirección baja” el dígito más alto de la edad se colocará en Alabama, y el más joven - en ah.

Para realizar ajustes, simplemente use el comando xchg al,ah:

mov ax, palabra ptr sotr1.age; en al age sotr1

o puedes hacerlo así:

El trabajo adicional con una matriz de estructuras se lleva a cabo de la misma manera que con una matriz unidimensional. Aquí surgen varias preguntas:

¿Qué hacer con el tamaño y cómo organizar la indexación de los elementos de la matriz?

Al igual que otros identificadores definidos en el programa, el traductor asigna un atributo de tipo al nombre del tipo de estructura y al nombre de la variable con el tipo de estructura. El valor de este atributo es el tamaño en bytes que ocupan los campos de esta estructura. Puede recuperar este valor usando el operador tipo.

Una vez que se conoce el tamaño de una instancia de estructura, organizar la indexación en una serie de estructuras no es particularmente difícil.

P.ej:

¿Cómo copiar un campo de una estructura al campo correspondiente de otra estructura? ¿O cómo copiar toda la estructura? Copiemos el campo. nombre tercer empleado en el campo nombre quinto empleado:

mas_sotr trabajador 10 dup()

mov bx, desplazamiento mas_sotr

mov si,(tipo trabajador)*2 ;si=77*2

mov di,(tipo trabajador)*4 ;si=77*4

Me parece que ser programador tarde o temprano hace que una persona parezca una buena ama de casa. Él, como ella, busca constantemente dónde guardar algo, recortar y preparar una cena maravillosa con un mínimo de ingredientes. Y si esto tiene éxito, entonces la satisfacción moral que se obtiene no es menor, y tal vez incluso mayor, que la de una maravillosa cena con un ama de casa. El grado de esta satisfacción, me parece, depende del grado de amor por la propia profesión.

Por otro lado, los éxitos en el desarrollo de software y hardware relajan un poco al programador y, con frecuencia, se observa una situación similar al conocido proverbio sobre la mosca y el elefante: para resolver algún problema menor se utilizan herramientas pesadas. cuya eficacia, en el caso general, es significativa sólo cuando se ejecutan proyectos relativamente grandes.

La presencia de los siguientes dos tipos de datos en el lenguaje probablemente se explica por el deseo del "ama de casa" de utilizar el área de trabajo de la mesa (RAM) de la manera más eficiente posible al preparar alimentos o colocar productos (datos del programa ).

Los comandos se pueden distinguir por su propósito (entre paréntesis se dan ejemplos de códigos de operación mnemónicos de los comandos del ensamblador de PC de IBM):

l realizar operaciones aritméticas (ADD y ADC - suma y suma con acarreo, SUB y SBB - resta y resta con préstamo, MUL e IMUL - multiplicación con signo y sin signo, DIV e IDIV - división con signo y sin signo, CMP - comparaciones, etc.);

l realizar operaciones lógicas (O, Y, NO, XOR, PRUEBA, etc.);

l transferencia de datos (MOV - reenvío, XCHG - intercambio, IN - entrada al microprocesador, OUT - salida del microprocesador, etc.);

l transferencia de control (ramas del programa: JMP - salto incondicional, CALL - llamada a procedimiento, RET - retorno del procedimiento, J* - salto condicional, LOOP - control de bucle, etc.);

l procesamiento de cadenas de caracteres (MOVS - transferencias, CMPS - comparaciones, LODS - cargas, SCAS - escaneos. Estos comandos se usan generalmente con el prefijo (modificador de repetición) REP;

l interrupciones del programa (INT - interrupciones de software, INTO - interrupción condicional por desbordamiento, IRET - retorno de una interrupción);

l control por microprocesador (ST* y CL* - configuración y reinicio de indicadores, HLT - parada, WAIT - espera, NOP - ralentí, etc.).

CON Lista llena Los comandos de ensamblaje se pueden encontrar en proceso.

Comandos de transferencia de datos

l MOV dst, src - transferencia de datos (mover - enviar de src a dst).

Transfiere: un byte (si src y dst están en formato byte) o una palabra (si src y dst están en formato word) entre registros o entre un registro y la memoria, y escribe un valor directo en un registro o memoria.

Los operandos dst y src deben tener el mismo formato: byte o palabra.

Src puede ser del siguiente tipo: r (registro) - registro, m (memoria) - memoria, i (impedancia) - valor inmediato. Dst puede ser de tipo r, m. No puede utilizar los siguientes operandos en un comando: rsegm junto con i; dos operandos de tipo m y dos operandos de tipo rsegm). El operando i también puede ser una expresión simple:

mov AX, (152 + 101B) / 15

La evaluación de expresiones se realiza sólo durante la traducción. No cambia de bandera.

l PUSH src: empujar una palabra a la pila (empujar - llevar a cabo; empujar hacia la pila desde src). Coloca el contenido de src (cualquier registro de 16 bits (incluido el registro de segmento) o dos celdas de memoria que contengan una palabra de 16 bits) en la parte superior de la pila. Las banderas no cambian;

l POP dst: saca una palabra de la pila (pop - pop; cuenta desde la pila hasta el dst). Elimina una palabra de la parte superior de la pila y la coloca en dst, cualquier registro de 16 bits (incluido el registro de segmento) o en dos celdas de memoria. Las banderas no cambian.

La programación a nivel de instrucción de máquina es el nivel mínimo en el que se pueden escribir programas. El sistema de instrucciones de la máquina debe ser suficiente para implementar las acciones requeridas emitiendo instrucciones al hardware de la computadora.

Cada comando de máquina consta de dos partes:

  • operativo: determinar “qué hacer”;
  • operando: definición de objetos de procesamiento, "qué hacer con".

El comando de máquina del microprocesador, escrito en lenguaje ensamblador, es una línea con la siguiente forma sintáctica:

etiqueta de comando/directiva operando(s);comentarios

En este caso, el campo requerido en la línea es un comando o directiva.

La etiqueta, el comando/directiva y los operandos (si los hay) están separados por al menos un espacio o un carácter de tabulación.

Si es necesario continuar con un comando o directiva en la siguiente línea, se utiliza el carácter de barra invertida: \.

De forma predeterminada, el lenguaje ensamblador no distingue entre letras mayúsculas y minúsculas al escribir comandos o directivas.

Líneas de código de ejemplo:

Cuenta db 1 ;Nombre, directiva, un operando
movimiento eax,0 ;Comando, dos operandos
cbw; Equipo

Etiquetas

Etiqueta en lenguaje ensamblador puede contener los siguientes símbolos:

  • todas las letras del alfabeto latino;
  • números del 0 al 9;
  • caracteres especiales: _, @, $, ?.

Se puede utilizar un punto como primer carácter de una etiqueta, pero algunos compiladores no recomiendan utilizar este carácter. Los nombres de ensamblador reservados (directivas, operadores, nombres de comandos) no se pueden utilizar como etiquetas.

El primer carácter de la etiqueta debe ser una letra o un carácter especial (pero no un número). La longitud máxima de la etiqueta es de 31 caracteres. Todas las etiquetas que estén escritas en una línea que no contenga una directiva de ensamblador deben terminar con dos puntos: .

equipos

Equipo le dice al traductor qué acción debe realizar el microprocesador. En un segmento de datos, un comando (o directiva) define un campo, espacio de trabajo o constante. En un segmento de código, un comando especifica una acción, como mover (mov) o agregar (add).

Directivas

El ensamblador cuenta con una serie de operadores que le permiten controlar el proceso de montaje y listado. Estos operadores se llaman directivas . Actúan sólo durante el proceso de compilación del programa y, a diferencia de los comandos, no generan código de máquina.

Operandos

Operando – un objeto en el que se ejecuta un comando de máquina o una declaración de lenguaje de programación.
Una instrucción puede tener uno o dos operandos, o ningún operando. El número de operandos está especificado implícitamente en el código de instrucción.
Ejemplos:

  • No hay operandos ret ;Regresar
  • Un operando inc ecx; aumentar ecx
  • Dos operandos suman eax,12 ;Suma 12 a eax

La etiqueta, el comando (directiva) y el operando no tienen que comenzar en ninguna posición particular de la línea. Sin embargo, se recomienda escribirlos en una columna para que el programa sea más fácil de leer.

Los operandos pueden ser

  • identificadores;
  • cadenas de caracteres entre comillas simples o dobles;
  • números enteros en sistemas numéricos binario, octal, decimal o hexadecimal.
Identificadores

Identificadores – secuencias de caracteres válidos utilizados para indicar objetos de programa, como códigos de operación, nombres de variables y nombres de etiquetas.

Reglas para registrar identificadores.

  • El identificador puede estar formado por uno o más caracteres.
  • Como símbolos puedes utilizar letras del alfabeto latino, números y algunos caracteres especiales: _, ?, $, @.
  • Un identificador no puede comenzar con un carácter de dígito.
  • La longitud del identificador puede tener hasta 255 caracteres.
  • El traductor acepta los primeros 32 caracteres del identificador e ignora el resto.
Comentarios

Los comentarios están separados de la línea ejecutable por un carácter; . En este caso, todo lo escrito después del punto y coma y hasta el final de la línea es un comentario. El uso de comentarios en un programa mejora su claridad, especialmente cuando el propósito de un conjunto de comandos no está claro. El comentario puede contener cualquier carácter imprimible, incluidos espacios. Un comentario puede abarcar toda la línea o seguir un comando en la misma línea.

Estructura del programa de montaje

Un programa escrito en lenguaje ensamblador puede constar de varias partes llamadas módulos . Cada módulo puede tener uno o más segmentos de datos, pila y código definidos. Cualquier programa ensamblador completo debe incluir un módulo principal o principal desde el cual comienza su ejecución. Un módulo puede contener segmentos de código, segmentos de datos y segmentos de pila, declarados mediante directivas apropiadas. Antes de declarar segmentos, debe especificar el modelo de memoria utilizando la directiva .MODEL.

Un ejemplo de un programa de “no hacer nada” en lenguaje ensamblador:

686P
.MODELO PLANO, LLAMADA ESTÁNDAR
.DATOS
.CÓDIGO
COMENZAR:

RETIRADO
FIN INICIO

Este programa contiene sólo un comando de microprocesador. Este comando es RET. Garantiza que el programa finalice correctamente. En general, este comando se utiliza para salir de un procedimiento.
El resto del programa se refiere al funcionamiento del traductor.
.686P: se permiten comandos en modo protegido de Pentium 6 (Pentium II). Esta directiva selecciona el conjunto admitido de instrucciones de ensamblador, indicando el modelo del procesador. La letra P indicada al final de la directiva informa al traductor que el procesador está funcionando en modo protegido.
.MODEL FLAT, stdcall - modelo de memoria plana. Este modelo de memoria se utiliza en Sistema operativo Ventanas. llamada estándar
.DATA es un segmento de programa que contiene datos.
.CODE es un bloque de programa que contiene código.
INICIO - etiqueta. En ensamblador, las etiquetas juegan un papel importante, lo que no se puede decir de los lenguajes modernos de alto nivel.
FINALIZAR INICIO: el final del programa y un mensaje al traductor de que la ejecución del programa debe comenzar con la etiqueta INICIO.
Cada módulo debe contener una directiva END, que marca el final del código fuente del programa. Todas las líneas que siguen a la directiva END se ignoran. Si omite la directiva END, se genera un error.
La etiqueta especificada después de la directiva END le dice al traductor el nombre del módulo principal desde el cual comienza la ejecución del programa. Si el programa contiene un módulo, se puede omitir la etiqueta después de la directiva END.




Arriba