05 Lenguaje Ensamblador Operaciones(ASM)

download 05 Lenguaje Ensamblador Operaciones(ASM)

of 29

Transcript of 05 Lenguaje Ensamblador Operaciones(ASM)

  • 5/21/2018 05 Lenguaje Ensamblador Operaciones(ASM)

    1/29

    5 El lenguaje ensamblador:

    operaciones

    En este captulo, vamos a ver cmo los programas hacen uso de la arquitectura delprocesador descrita en el captulo anterior. Para esto necesitamos conocer ellenguaje de la mquina. Este captulo presenta los rudimentos del lenguajeensamblador centrado en el caso particular de la IA32.

    La presentacin de las operaciones en ensamblador se hace estableciendo unarelacin con sus equivalentes en los lenguajes de alto nivel. Esto presenta dosventajas: la primera, que se parte de algo conocido y se tiene un punto de referenciapara entender cmo usar el ensamblador; la segunda, que se entiende cmoefectan realmente sus operaciones los lenguajes de alto nivel.

    5.1 PRESENTACIN DEL LENGUAJE ENSAMBLADOR

    Antes de entrar en el lenguaje ensamblador propiamente dicho, haremos algunasprecisiones sobre el lenguaje de mquina.

    Lenguaje de mquina

    Una instruccin es una operacin que se efecta sobre unos operandos (operandosfuente) y produce un resultado (operando destino). Es necesario especificar elcdigo de operacin y los operandos; para estos ltimos se debe especificar dndese encuentran: en la instruccin misma, en los registros o en memoria. En esteltimo caso, la direccin puede ser esttica (direccionamiento directo) o dinmica

    (direccionamiento indexado, indirecto, etc.).Como hemos mencionado anteriormente, las instrucciones estn en la memoriacodificadas en binario. La codificacin se parte en varios campos; lo que hemosllamado el formato de instruccin.

    Vemos un ejemplo: tenemos una mquina de 16 bits direcciones y datos, con 16registros, 64 operaciones e instrucciones con dos operandos; el primer operandosiempre es un registro y el segundo puede tener uno de 4 modos dedireccionamiento: inmediato, directo, de registro e indirecto por registro.

    5 El lenguajeensamblador:

    operaciones

  • 5/21/2018 05 Lenguaje Ensamblador Operaciones(ASM)

    2/29

    22

    Ellenguajeensamblador:operaciones Captulo5.

    En una mquina como esta tenemos que codificar cuatro elementos:

    Cdigo de operacin. Puesto que hay 64 operaciones, necesitamos 6 bits paracodificarlas. La codificacin es arbitraria en principio; puede que haya algncondicionamiento debido a la estructura, pero, en general, no hay mayores

    restricciones para establecerla. Se tratar entonces de una codificacin delestilo: 000000 es ADD, 000001 es SUB, 000010 es AND, etc.

    Modo de direccionamiento del segundo operando. Como el primer operandoes siempre un registro, no es necesario codificar su forma dedireccionamiento. En cuanto al segundo, dado que puede tener unocualquiera de cuatro modos de direccionamiento, necesitamos 2 bits paracodificarlo; algo del estilo: 00 es inmediato, 10 es directo, 01 es de registro y11 es indirecto por registro.

    Primer operando. El primer operando es un registro, puesto que hay 16,necesitamos 4 bits para codificarlo.

    Segundo operando. Si el segundo operando es de modo inmediato o directo,necesitamos 16 bits para codificarlo puesto que la mquina es de 16 bits;si es de registro o indirecto por registro, necesitamos 4 bits para codificarlo.

    El segundo operando introduce un problema: segn su modo de direccionamientorequiere un nmero diferente de bits. Tenemos dos posibles soluciones:

    Reservar un nmero fijo de bits. Tendramos que reservar el mximo posible;16, en este caso. Eso implica que, cuando el operando sea un registro, sedesperdiciara espacio, pero tendramos un solo tamao de instruccin.

    Tener un nmero variable de bits. En este caso, el operando tendra 4 16bits dependiendo del modo de direccionamiento. Esto implica que

    tendramos dos formatos de instruccin, uno ms largo que el otro. En esteejemplo vamos a tomar esta opcin.

    Para los dos primeros modos de direccionamiento, el formato de instruccin es:

    Operacin Modo Registro Constante o Direccin6 bits 2 bits 4 bits 16 bits

    En total, 28 bits; no es mltiplo de 8, as que no es un nmero entero de bytes. Estonos conduce a introducir un relleno, basura, que no codifica nada, para tener unnmero entero de bytes:

    Operacin Modo Relleno Registro Constante o Direccin

    6 bits 2 bits 4 bits 4 bits 16 bits

    Ahora una instruccin de este tipo tendra 4 bytes.

    Para los otros dos modos de direccionamiento tenemos:

    Operacin Modo Registro Registro6 bits 2 bits 4 bits 4 bits

    Es decir dos bytes.

  • 5/21/2018 05 Lenguaje Ensamblador Operaciones(ASM)

    3/29

    5.1 Presentacindellenguajeensamblador 23

    Con estas convenciones la instruccin: SUB reg3, 5, se codificara:

    000001 00 0011 0000 00000000 00000101

    En tanto que la instruccin: SUB reg3, [reg5], se codificara:

    000001 11 0011 0101Por supuesto, la unidad de control sabe "partir" la instruccin para extraer lainformacin que necesita. Esto es, justamente, el paso del ciclo de ejecucin quellamamos decodificacin de instruccin.

    Lenguaje ensamblador

    Es fcil darse cuenta de que programar escribiendo largas series de nmerosbinarios no es nada cmodo. Por esto, se pens en desarrollar un lenguajesimblico: en lugar de nmeros binarios vamos a escribir palabras que designan laoperacin, los operandos, el modo de direccionamiento, etc.

    Este es el lenguaje ensamblador. Puesto que es simblico, la mquina no lo puedeinterpretar directamente esta solo puede interpretar el lenguaje binario, por loque necesitamos un programa traductor que se encargue de leer un programa enensamblador y lo traduzca a binario; este es elprograma ensamblador.

    El lenguaje ensamblador es una notacin del estilo de la que usamos para expresarlos programas de la mquina en el captulo anterior. Note que esta notacin es muycercana al formato de la instruccin: cdigo de operacin, primer operando ysegundo operando solo el modo de direccionamiento se encuentra en otro lugar; por lo cual la tarea del ensamblador es relativamente sencilla: traducir cada unade las palabras a su cdigo binario y con ellas ensamblar la instruccin; de aquviene su nombre de ensamblador.

    El hecho de tener este intermediario entre el programador y la mquina introduceuna serie de ventajas. En primer lugar, claro est, los nombres simblicos; eldiseador del ensamblador elige estos nombres segn lo que le parezca mscmodo. Por ejemplo, para los registros, podemos elegir los nombres reg0, reg1,etc. O podemos elegir algo como $0, $1, etc. O, como Intel, eax, ebx, etc.

    Pero hay otras ventajas; por ejemplo, podemos permitir que el programador escribalos nmeros en la base que desee 2, 10, 16 y dejar que el ensamblador lostraduzca a binario. En el caso del ensamblador de Microsoft MASM, MacroASseMbler, este acepta que los nmeros se escriban en diferentes bases: 26 26D(base 10), 1AH (base 16), 11010B (binario) y 32Q (octal), y los traduce a binario.1

    Tambin, se puede introducir un mayor nivel de abstraccin. Por ejemplo, ennuestra notacin, el modo de direccionamiento est asociado al operando; no es uncampo independiente como lo es en la instruccin de mquina.

    Hay otras ventajas que trae consigo el ensamblador que veremos posteriormente.

    1En el texto, segn lo que parezca ms claro, usaremos una u otra base.

  • 5/21/2018 05 Lenguaje Ensamblador Operaciones(ASM)

    4/29

    24

    Ellenguajeensamblador:operaciones Captulo5.

    Como se mencion al comienzo, en las secciones siguientes vamos a partir de lasinstrucciones de alto nivel, y a mostrar cmo pueden ser implementadas usando lasinstrucciones de la mquina. Empezamos por movimiento de informacin, es decir,el equivalente de las asignaciones; despus veremos la forma de evaluarexpresiones y, por ltimo, cmo se hacen las declaraciones.

    5.2 LA ASIGNACIN

    La instruccin de mquina que permite implementar la asignacin es "mov" (delingls move). En realidad, se puede decir que hay varias instrucciones demovimiento: entre registros, de memoria a registro y de registro a memoria. Peropodemos hacer la abstraccin y suponer que es una sola; el tipo de los operandos ysu posicin nos indicar, en cada caso, cul es la operacin deseada.

    Como se mencion anteriormente, es una instruccin de dos operandos, y asigna elde la derecha al de la izquierda. Lo mismo que en los lenguajes de alto nivel, elelemento de la derecha no pierde su valor original; pero el elemento que de laizquierda adquiere el valor del otro.

    Esta instruccin permite realizar diversas acciones:

    Traer una variable (cargar) de memoria a un registro. Las operaciones no sepueden efectuar directamente sobre las variables en memoria; en todo caso,aunque se pudiera, es ms rpido hacer las operaciones en los registros. Poresto es necesario poder trasladar las variables de memoria a registros:

    mov ax, [122]

    Actualizar una variable en memoria con el valor de un registro. Despus derealizados los clculos es necesario actualizar el valor de la variable en

    memoria (el registro es una suerte de variable temporal, pero es necesarioactualizar la variable original):

    mov [122], ax

    Mover valores entre registros. Mientras se hacen los clculos, puede sernecesario replicar el valor en otros registros:

    mov bx, ax

    Inicializar registros o variables en memoria. Como en los lenguajes de altonivel, en ocasiones es necesario asignar un valor constante:

    mov [122], 4

    mov bx, 4

    A continuacin, estudiaremos varios casos de asignacin. Para no complicarnos condirecciones de memoria, trabajaremos con nombres simblicos de variables; esdecir, en lugar de escribir mov [122],4, escribiremos algo del estilo mov x,4.

    Donde suponemos que la variable x est en la posicin 122 de memoria.Posteriormente veremos que el ensamblador efectivamente presta este servicio denombres simblicos para las variables.

  • 5/21/2018 05 Lenguaje Ensamblador Operaciones(ASM)

    5/29

    5.2 Laasignacin 25

    Asignacin simple

    Tomemos el siguiente segmento de cdigo en C:

    int x, y;y = 3;

    x = y;

    La primera asignacin no tiene problema:

    mov y, 3

    En cuanto a la segunda, puesto que en la IA32 no se pueden tener dos operandos enmemoria, nos tocara pasar por un registro intermediario:

    mov ecx, ymov x, ecx

    Lo anterior es la traduccin ms formal y literal; sin embargo, un programadorinteligente, o un compilador con optimizacin, podran efectuar otras acciones. Por

    ejemplo, podramos mantener la variable y, temporalmente, en el registro ebx, conlo cual el cdigo se convertira en:

    mov ebx, 3mov x, ebx

    Este cdigo es ms eficiente que el anterior porque solo hace un acceso a memoriacontra tres del otro. Por supuesto, es posible que ms adelante en el programanos toque actualizar la variableyen memoria.

    Los compiladores asignan variables en los registros en diversas circunstancias, porejemplo, si se trata de una variable temporal que solo se utiliza brevemente parahacer unos clculos, es ms fcil hacerlos en los registros y no crearla en memoria;

    por otro lado, si una variable se usa mucho en algn momento del programa, esms eficiente mantenerla en un registro (luego, cuando ya no est siendo tanutilizada, se actualizar en memoria).

    Al hacer asignaciones, se debe tener en cuenta el tamao de las variables: loscaracteres se manejan en registros de 8 bits (ah, al, bh, etc.), los enteros cortos enregistros de 16 bits (ax, bx, etc.) y los enteros en registros de 32 bits (eax, ebx,etc.). Los nmeros de punto flotante se manejan en unos registros especiales que seencuentran en la unidad de punto flotante. Los apuntadores, como todas lasdirecciones en general, se manejan sobre 32 bits, es decir usandoeax, ebx, etc.

    Por ejemplo, el mismo cdigo anterior, pero usando caracteres:

    Cdigo C Cdigo Ensamblador

    char x, y;y = a;x = y;

    mov bl, amov x, bl

    Note que, para facilitar el manejo de caracteres, el ensamblador permite escribir loscaracteres en notacin simblica. No olvide, sin embargo, que es slo una manera

  • 5/21/2018 05 Lenguaje Ensamblador Operaciones(ASM)

    6/29

    26

    Ellenguajeensamblador:operaciones Captulo5.

    de representar el cdigo ASCII correspondiente. Dicho de otra forma, 'a' y 61H soncompletamente equivalentes para el ensamblador.

    Asignacin con apuntadores

    En lenguaje de mquina, un apuntador es una variable (de 32 bits) que contiene ladireccin de otra variable. Por ejemplo, si en la posicin 1000 de memoria tenemosun entero, y en la posicin 400 queremos tener un apuntador a este entero, bastacon guardar el valor 1000 en la posicin 400. Una forma de hacer esto es:

    mov [400], 1000

    Esta es la realidad, pero es mejor pensar en trminos abstractos y no en trminosoperativos. Pensar en trminos de: "ebx contiene la direccin de otra variable enmemoria", genera confusin; es mejor pensar "ebx apunta a esta variable".

    Para los apuntadores se usa el direccionamiento indirecto. A continuacin semuestra un ejemplo de su uso a la izquierda y a la derecha de una asignacin:

    Cdigo C Cdigo Ensambladorint x, y;int * p;x = *p;

    mov ebx, pmov ecx, [ebx]mov x, ecx

    *p = y; mov ecx, ymov [ebx], ecx

    Tenga presente que los apuntadores son valores de 32 bits, no necesariamente aslo apuntado por ellos. Por ejemplo:

    Cdigo C Cdigo Ensamblador

    char * p, *q;

    *p = *q;

    mov ebx, q

    mov cl, [ebx]mov ebx, pmov [ebx], cl

    p = q; mov ecx, qmov p, ecx

    La primera asignacin mueve caracteres; la segunda, apuntadores. Note que laprimera no modifica p, sino lo apuntado por p, en tanto que la segunda s modificap.

    Asignacin con vectores

    En el caso de los vectores se usa el direccionamiento indexado. Se debe tener

    presente que en los lenguajes de alto nivel, para acceder a un elemento, se usa unndice; en ensamblador, se usa un desplazamiento. En el caso de los caracteres losdos conceptos coinciden; empezaremos por este caso:

    Cdigo C Cdigo Ensamblador

    int i;char v[100], c;c = v[i];

    mov edi, imov cl, v[edi]mov c, cl

  • 5/21/2018 05 Lenguaje Ensamblador Operaciones(ASM)

    7/29

    5.2 Laasignacin 27

    Como hemos mencionado anteriormente, para obtener el desplazamiento en el casogeneral, es necesario multiplicar el ndice por el tamao de los elementos; porejemplo, para un vector de short intes necesario multiplicar el ndice por 2, o,lo que es lo mismo, sumar el ndice consigo mismo:

    Cdigo C Cdigo Ensambladorint i;short int v[100], s;s = v[i];

    mov edi, iadd edi, edimov cx, v[edi]mov s, cx

    Esta es una forma de hacerlo; pero tambin, es posible usar el indexamiento conescalamiento:

    Cdigo C Cdigo Ensamblador

    int i;

    short int v[100], s;s = v[i];

    mov edi, i

    mov cx, v[2*edi]mov s, cx

    Un vector de enteros se trata igual que el anterior pero usando un escalamiento de4, y un registro de 4 bytes eax, por ejemplo.

    En el caso general, si se tiene un vector cuyos elementos ocupan n bytes cada uno,la posicin del i-simo elemento viene dada por i*nver fig. 5.1. Recuerde que elescalamiento solo se puede utilizar si n es 1, 2, 4 8; en otros casos es necesariohacer la multiplicacin explcitamente.

    Tamao de las variables

    Si las variables son ms grandes que cualquier registro por ejemplo, si son longlongo estructuras, es necesario implementar la asignacin copiando por partes;eventualmente con iteracin. Por ejemplo:

    Cdigo C Cdigo Ensamblador

    long long x, y;x = y;

    mov ebx, ymov x, ebxmov ebx, y+4mov x+4, ebx

    Note que x y y designan posiciones de memoria, en consecuencia, en notacin

    Fig. 5.1.Relacin entre ndices y desplazamientos para varios tipos de datos

    DireccinMemoria Contenido

    Tipos de datos

    - char 0 1 2 3 4 5 6 7 8

    - short int 0 1 2 3

    - int 0 1

    n+0 n+1 n+2 n+3 n+4 n+5 n+6 n+7 n+8

  • 5/21/2018 05 Lenguaje Ensamblador Operaciones(ASM)

    8/29

    28

    Ellenguajeensamblador:operaciones Captulo5.

    simblica, x+4no es el contenido de xms 4, sino la posicin de memoria que seencuentra 4 bytes adelante de x. Puesto que xes un long long, ocupa 8 bytes; los4 primeros estn en las posiciones xa x+3y los 4 segundos estn dex+4a x+7.

    Qu ocurre cuando se mezclan tamaos? Segn la definicin de C, y debe

    truncarse a su byte menos significativo:

    Cdigo C Cdigo Ensamblador

    int y;char x;x = y;

    mov ebx, ymov x, bl

    Recuerde que bles el byte menos significativo deebx.

    Tambin est el caso contrario: se asigna algo ms pequeo a algo ms grande:

    char y;int x;

    x = y;

    Segn la definicin de C, la variable ydebe extenderse al tamao de x; es decir, sedebe convertir el valor deyde 8 a 32 bits. Esto depende de si ytiene signo o no:

    Nmero sin signo: basta con agregarle a y24 ceros a la izquierda.

    Nmero con signo: el bit de signo de yse replica 24 veces a la izquierda: si elsigno es cero, el nmero sigue siendo positivo; si es 1, se mantiene negativo.

    Lo primero es fcil de hacer, lo segundo es un poco ms difcil. A continuacindamos una posible solucin que se entender plenamente ms adelante:

    Cdigo C Cdigo Ensambladorint x;unsigned char y;x = y;

    mov ebx, 0mov bl, ymov x, ebx

    int x;signed char y;x = y;

    mov bl, yshl ebx, 24sar ebx, 24mov x, ebx

    Ahora, en realidad, es ms fcil, porque la IA32 tiene instrucciones que hacenesto!: movzx (MOVe with Zero eXtend) y movsx (MOVe with Sign eXtend). Enconsecuencia los dos ejemplos anteriores se resuelven as:

    Cdigo C Cdigo Ensamblador

    int x;unsigned char y;x = y;

    movzx ebx, ymov x, ebx

    int x;signed char y;x = y;

    movsx ebx, ymov x, ebx

  • 5/21/2018 05 Lenguaje Ensamblador Operaciones(ASM)

    9/29

    5.2 Laasignacin 29

    Aqu la pregunta interesante es: vale la pena incluir estas instrucciones en unaarquitectura? Por supuesto, son tiles, pero, se necesitan con frecuencia?, no nosvolvern la mquina un poco ms complicada sin ganar mucho con ello? Este es eltipo de balances entre hardware y software que un diseador debe resolver.

    CastEl programador en C percibe el cast como una conversin entre tipos de datos.Pero, desde el punto de vista de la mquina, el cast ejecuta diversas acciones segnel caso:

    Conversin entre el mismo tipo de datos con diferentes tamaos. Este es elcaso de la conversin entre shorte int, etc. Se trata como se describi en laseccin anterior.

    Conversin entre diferentes tipos de datos del mismo tamao. Este es el casode la conversin entre apuntadores, o entre enteros y apuntadores, etc. Setrata de la siguiente manera:

    Cdigo C Cdigo Ensamblador

    int * p;char * q;p = (int *)q;

    mov ebx, qmov p, ebx

    Es decir, en lo esencial, no se hace nada: sencillamente se asigna una variablea la otra.

    Conversin entre tipo de datos con representaciones diferentes. Este es elcaso de la conversin entre float e int, etc. En este caso es necesariogenerar cdigo para transformar una representacin en la otra (por ejemplo,llamar una funcin para convertir de entero a flotante).

    5.3 INSTRUCCIONES DE LA MQUINA

    En ensamblador no se puede escribir expresiones como en los lenguajes de altonivel. Para evaluar expresiones, hay que proceder paso a paso, evaluando cadaoperacin en su turno. Para esto se dispone de las instrucciones de la mquina, lascuales implementan diversidad de operaciones. Empezaremos introduciendoalgunas de estas instrucciones.

    Instrucciones aritmticas

    La instruccin ADD tiene dos operandos, y adiciona el segundo al primero. Los

    operandos son registros o posiciones de memoria; en general, pueden tenercualquier modo de direccionamiento, aunque, como es usual, los dos operandos nopueden estar en memoria. Los operandos pueden ser de 8, 16 32 bits, pero los dosdeben tener el mismo tamao. No es posible sumar directamente un operando de 8con uno de 16; es necesario convertir el nmero de 8 bits a 162.

    2O el de 16 a 8, pero es ms riesgoso porque pueden perderse dgitos.

  • 5/21/2018 05 Lenguaje Ensamblador Operaciones(ASM)

    10/29

    3

    Ellenguajeensamblador:operaciones Captulo5.

    La instruccin SUBresta el segundo operando al primero; de resto tiene las mismascaractersticas queADD.

    La instruccin NEG sirve para obtener el complemento a dos de un nmero. Tieneun solo parmetro, y deja el resultado en el mismo; este puede ser de 8, 16 32 bits

    y tener cualquier modo de direccionamiento.3En cuanto a la multiplicacin, existen dos tipos de instrucciones; las del primer tiposon las ms sencillas y las explicaremos en primer lugar (tambin es recomendableutilizarlas siempre que se pueda). Estas instrucciones se llaman IMUL (IntegerMULtiply), todas sirven para multiplicar nmeros con signo o sin signo. Tienen 3sintaxis:

    imul reg, const

    imul reg, oper, const

    imul reg, oper

    Donde reges un registro, constuna constante y operun registro o una posicin de

    memoria. Los operandos pueden ser de 16 de 32 bits. Las de dos operandosmultiplican el uno por el otro y dejan el resultado en el registro. La de tresoperandos multiplica los dos ltimos y deja el resultado en el registro.

    El segundo tipo de instrucciones de multiplicacin son una herencia del 8086. Enprimer lugar hay dos: MUL e IMUL; la primera sirve para multiplicar nmeros sinsigno; la segunda, para nmeros con signo. En cualquier caso, tienen un solooperando, que puede ser una posicin de memoria o un registro, y puede tener 8, 16 32 bits:

    mul oper

    El otro operando es implcito, y depende de cuntos bits tiene oper:

    ax al * oper8

    dx:ax ax * oper16

    edx:eax eax * oper32

    Donde la notacin reg1:reg2denota la concatenacin de los dos registros.4Noteque el uso de ax, dx, etc. no es un ejemplo: se usan exactamente esos registros.

    Nada lo obliga a utilizar la parte del resultado que va en dxo en edx: si sabe que elresultado cabe en axo en eaxsegn sea el caso, puede despreciar la parte alta.No olvide que, aun en ese caso, la instruccin afecta a dx o edx as sea

    ponindolos en cero.La divisin es el complemento de la instruccin de multiplicacin que acabamos dedescribir. Hay dos: DIV e IDIV, que sirven para dividir nmeros sin signo y con

    3Excepto inmediato, que no tiene sentido.

    4Note que la representacin del producto de dos nmeros de nbits puede requerir 2*nbits, por estoes necesario que el resultado tenga el doble de tamao que los operandos.

  • 5/21/2018 05 Lenguaje Ensamblador Operaciones(ASM)

    11/29

    5.3 Instruccionesdelamquina 3

    signo, respectivamente. Como la multiplicacin, tienen un solo operando posicinde memoria o registro:

    div oper

    El otro operando es implcito, y depende de cuntos bits tiene oper:

    al ax / oper8; ah ax mod oper8

    ax dx:ax / oper16; dx dx:ax mod oper16

    eax edx:eax / oper32; edx edx:eax mod oper32

    Note que la divisin, a diferencia de las instrucciones anteriores, retorna dosresultados: el cociente y el residuo.

    Por supuesto, adems de las descritas, existen otras instrucciones tiles, como DECe INC, pero no presentan mayores dificultades y no las trataremos aqu; consultarun manual para ver su operacin.

    Instrucciones lgicasLas instrucciones para el manejo de expresiones lgicas son las usuales:AND, OR,XOR(o-excluyente) y NOT.

    En su funcionamiento, son parecidas a las aritmticas: todas (excepto NOT) tienendos operandos. Como es usual, operan el primero con el segundo y guardan elresultado en el primero. En cuanto a NOT, invierte los bits de su operando dejandoel resultado en el mismo operando.

    Es importante resaltar que todas estas operaciones se efectan bit a bit, es decir,equivalen a los operadores de C: &, |, ^ y ~ (no equivalen a &&, || y !).

    Instrucciones de corrimientoEstas instrucciones son un poco menos usuales que las vistas hasta el momento; sinembargo, algunas de ellas existen en C: >> y >>).

    Hay de dos tipos: corrimientos y las rotaciones; y se pueden hacer en dosdirecciones: derecha e izquierda. Adems, los corrimientos pueden ser lgicos oaritmticos y las rotaciones pueden ser simples o a travs del bit de acarreo.

    En resumen, tenemos:

    Nombre Sigla Accin

    SHift Right SHR Corrimiento a la derechaSHift Left SHL Corrimiento a la izquierdaShift Arithmetic Right SAR Corrimiento aritmtico a la derechaROtate Right ROR Rotacin a la derechaROtate Left ROL Rotacin a la izquierdaRotate through Carry Right RCR Rotacin a la derecha a travs del carryRotate through Carry Left RCL Rotacin a la izquierda a travs del carry

  • 5/21/2018 05 Lenguaje Ensamblador Operaciones(ASM)

    12/29

    32

    Ellenguajeensamblador:operaciones Captulo5.

    Todos tienen dos operandos: el primero es el que se quiere correr o rotar, elsegundo indica cuntos bits se desea desplazarlo. El resultado se guarda en elprimer operando.

    El primer operando se puede indicar con cualquier modo de direccionamiento

    (excepto inmediato, no tendra sentido). El segundo puede ser una constante o elregistro cl. As, si queremos correr el registro ax dos posiciones a la derecha,escribimos:

    shr ax, 2

    Pero, si queremos hacer un corrimiento de nposiciones, donde nes una variable, alo apuntado por esi, debemos escribir:

    mov cl, nshr [esi], cl

    El ltimo bit en salir se guarda en el bit de acarreo. En el caso de los corrimientos,entran ceros por el otro extremo para remplazar los bits perdidos. En el caso de lasrotaciones, el bit que sale por un extremo vuelve a entrar por el otro.

    Las rotaciones a travs del bit de acarreo son como las rotaciones simples, perotratando el bit de acarreo como si fuera parte del registro.

    En cuanto al corrimiento aritmtico a la derecha, en lugar de recibir ceros por elextremo izquierdo, el bit de signo se va replicando con cada corrimiento. Es decir, sitenemos 10001000, y le hacemos un corrimiento aritmtico a la derecha,obtenemos 11000100.

    La fig. 5.2 muestra una sntesis de estas instrucciones.

    5.4 EVALUACIN DE EXPRESIONES

    Toda expresin tiene un orden de evaluacin que viene dado por los parntesis y laprioridad de los operadores (ver fig. 5.3). En ensamblador es necesario evaluarexpresin por expresin siguiendo el orden indicado; los resultados intermedios sepueden almacenar en registros o en variables temporales en memoria. En lo quesigue mostramos cmo se hace esta evaluacin.

    Los recuadros de la figura 5.3 denotan un orden de evaluacin: cunto ms claros,ms pronto deben ser evaluados, porque otras expresiones dependen de ellos. Noteque puede haber diversos ordenes de evaluacin; por ejemplo, en la figura 5.3,

    Fig. 5.2.Rotaciones y corrimientos

    CarryRegistro

    RCR0

    ROR

    SHRSAR

  • 5/21/2018 05 Lenguaje Ensamblador Operaciones(ASM)

    13/29

    5.4 Evaluacindeexpresiones 33

    podemos empezar por a*bo por e/2. Una posible evaluacin es:

    Cdigo C CdigoEnsamblador

    a*b mov ebx, a

    imul ebx, ba*b + c add ebx, c

    a*b + c + 3 add ebx, 3

    e/2 mov eax, ecdqmov ecx, 2idiv ecx

    d - e/2 mov edx, dsub edx, eax

    (a*b + c + 3)*(d - e/2) imul ebx, edx

    -((a*b + c + 3)*(d - e/2)) neg ebx

    Algunos comentarios: Note que despus de evaluar (a*b + c + 3), el resultadoqueda en ebx, lo cual implica que este registro no se puede usar en lo subsiguiente;estamos usando ebx como una variable temporal. En la medida en que la expresinse vuelva ms complicada, se necesitarn ms temporales, lo cual ir conduciendo aque se agoten los registros.

    Una estrategia para minimizar el impacto de esto consiste en evaluar primero lasexpresiones ms complicadas, de esta manera se tienen ms registros disponiblescuando se estn evaluando las expresiones que requieren ms temporales. Si aunas no es suficiente, ser necesario guardar algunos registros en variablestemporales en memoria.

    La divisine/2luce ms extraa; la situacin es la siguiente: la divisin de 32 bits

    supone que el dividendo est en edx:eax; el programa carga e en eax, pero esnecesario expandir este nmero para que ocupe la pareja de registros edx:eax; lainstruccin cdqConvert Doubleword to Quadwordhace exactamente eso.

    Note que en el momento de hacer la divisin ya tenemos ocupados cuatro registros:eax, ebx, ecx y edx; es decir, para esta expresin, que no es demasiadocomplicada, alcanzamos a ocupar la mitad de los registros disponibles.

    En ocasiones, analizando el cdigo es posible disminuir el nmero de registros; por,ejemplo, en nuestro caso, podemos evaluar la resta d-e/2de la siguiente manera:

    neg eaxadd eax, d

    Fig. 5.3.Orden de evaluacin

    -( ( a*b + c + 3 ) * ( d e/2 ) )( a*b + c + 3 ) * ( d e/2 )( a*b + c + 3 )a*b + ca*b ( d e/2 )e/2

  • 5/21/2018 05 Lenguaje Ensamblador Operaciones(ASM)

    14/29

    34

    Ellenguajeensamblador:operaciones Captulo5.

    As no tenemos que usar el registroedx.

    En cuanto a la divisin, podemos recurrir a un truco que usa menos registros y esms eficiente en ejecucin:

    mov eax, e

    sar eax, 1

    En principio, un corrimiento a la derecha equivale a dividir por 2. Aunque este tipode trucos se suele usar, es necesario hacerlo con cuidado; por ejemplo, en este caso,el corrimiento a la derecha no es completamente equivalente a la divisin. Lasituacin es as: los corrimientos se comportan como la divisin euclidiana; enconsecuencia, -1/2 = -1 y -3/2 = -2, etc. Es decir, cuando el dividendo es negativo,redondea al entero negativo inferior; en cambio, en la misma situacin, la divisinde los lenguajes de alto nivel redondea al entero superior: -1/2 = 0 y -3/2 = -1, etc.

    Expresiones y asignaciones

    En principio, las expresiones retornan un valor pero no modifican variables. Sinembargo en C se presentan dos circunstancias:

    Hay operadores que retornan un valor pero tambin modifican una variable.

    Hay asignaciones que efectan una operacin.

    En realidad, en C, podemos reducir todo a la primera afirmacin: para C laasignacin es un operador que modifica la variable a la izquierda y retorna comovalor la variable a la derecha. Por esto en C se puede escribir:

    a = b = 1;

    En esta expresin ay bquedan valiendo 1.

    Sin embargo, por claridad, trataremos las dos situaciones por aparte.Operadores con efecto de borde

    Los operadores de C ++ y --, adems de retornar un valor, afectan una variable.Adicionalmente, la semntica de estos operadores depende de si estn antes odespus de la variable: no es lo mismo++iquei++. En los dos casos la variable seincrementa en 1, pero, la primera expresin retorna el valor de la variableincrementada, en tanto que la segunda retorna el valor antes de incrementar:

    Cdigo C Cdigo Ensamblador

    char x;char * p;

    x = *p++;

    mov ebx, pmov dh, [ebx]

    mov x, dhinc ebxmov p, ebx

    x = *++p; mov ebx, pinc ebxmov dh, [ebx]mov x, dhmov p, ebx

  • 5/21/2018 05 Lenguaje Ensamblador Operaciones(ASM)

    15/29

    5.4 Evaluacindeexpresiones 35

    Note que el cdigo es esencialmente el mismo excepto por la posicin delincremento.

    Operadores de asignacin

    En C existen mltiples operadores del estilo +=. Son operadores que, ms que

    asignar, acumulan; es decir, almacenan un valor en una variable pero efectuandouna operacin con el valor que ya se encuentra en ella. A continuacin mostramosun ejemplo:

    Cdigo C Cdigo Ensamblador

    int x, y;x += y;

    mov ebx, yadd x, ebx

    Expresiones y direccionamiento

    En las expresiones estudiadas hasta ahora siempre operamos sobre datos; lasexpresiones tambin operan sobre direcciones.5

    Tenemos expresiones como: v[i], *p, p++,p+i,p-q, &x, s.x, p->x; todas lascuales son alguna forma de operacin sobre una direccin. A continuacintrataremos algunas particularidades relacionadas con estas operaciones.

    Apuntadores

    Los apuntadores son variables de tipo direccin; en principio, su contenido es unnmero que corresponde a alguna direccin de la memoria. Como mencionamosanteriormente, cuando usamos el apuntador (p), estamos hablando del contenidodel apuntador la direccin en s; cuando usamos la indireccin (*p), estamoshablando de la entidad apuntada. En consecuencia, p y *p tienen tipos de datosdiferentes: si pes un apuntador a un entero, *pes un entero. Ahora, *p no solo es

    un valor entero, sino que corresponde a una variable en memoria; por ende puedeser usado en contextos donde solo se pueden usar variables por ejemplo, (*p)++,o aparecer a la izquierda en una asignacin. A continuacin presentamos algunosejemplos de traduccin:

    Cdigo C Cdigo Ensamblador

    char x;char * p;*p = x;

    mov ebx, pmov dh, xmov [ebx], dh

    (*p)++; mov ebx, pinc [ebx]

    *(p++) = x; mov ebx, p

    mov dh, xmov [ebx], dhinc ebxmov p, ebx

    5Tambin se puede ver como que las direcciones son un tipo de datos que tiene sus particularidadespropias diferentes de los enteros, caracteres, etc.

  • 5/21/2018 05 Lenguaje Ensamblador Operaciones(ASM)

    16/29

    36

    Ellenguajeensamblador:operaciones Captulo5.

    Note la diferencia entre las dos ltimas asignaciones: en la tercera, a lo apuntado sele est asignando x, y, posteriormente, se incrementa el apuntador;6en la segunda,solo se incrementa lo apuntado, y no se modifica el apuntador.

    Con respecto a los incrementos en los apuntadores, en los lenguajes de alto nivel, el

    programador no se preocupa por el tamao de los tipos de datos; no as enensamblador, donde el tamao de las entidades se vuelve un aspecto relevante en laprogramacin.

    En concreto, en C escribimos p++sin preocuparnos del tipo de datos apuntado porp. Los programadores en ensamblador, o los compiladores al generar cdigo, sdeben ocuparse de este aspecto. En efecto, normalmente, si se incrementa elapuntador, es porque est apuntando a un vector y queremos ponerlo a apuntar alsiguiente elemento, luego debe incrementarse en lo que ocupe el elemento enmemoria; as, un apuntador a entero debe incrementarse de 4 en 4 porque unentero ocupa 4 bytes (ver fig. 5.4). Por ejemplo:

    Cdigo C Cdigo Ensambladorchar * p;short int * q;int * r;p++; q++ ; r++;

    add p, 1add q, 2add r, 4

    Lo dicho sobre el incremento es aplicable en general a las operaciones aritmticascon apuntadores.

    p+i: debe multiplicarse la ipor el tamao del elemento apuntado y esto sesuma al contenido de p.

    p-q: debe dar como resultado el nmero de elementos que hay entre py q;

    en consecuencia, corresponde a la resta de py qdividida por el tamao delelemento apuntado.

    Vectores

    C es un lenguaje muy basado en apuntadores, por lo cual la notacin vectorialpuede ser considerada azcar sintctico: el programador se siente cmodo conella, pero, en realidad, en el fondo son los mismos apuntadores.

    6Como nota al margen, debido a la prioridad de operadores en C, *(p++)es lo mismo que *p++.

    Fig. 5.4.Relacin entre incrementos de apuntadores y desplazamientos

    DireccinMEMORIA Contenido

    ndice 0 1

    n+0 n+1 n+2 n+3 n+4 n+5 n+6 n+7 n+8

    p p+1 p+2

  • 5/21/2018 05 Lenguaje Ensamblador Operaciones(ASM)

    17/29

    5.4 Evaluacindeexpresiones 37

    Esto va a tal punto que cuando el compilador encuentra expresiones del tipo:

    expr1[expr2]

    lo primero que hace es traducirlas a:

    *(expr1+expr2)Es decir, la notacin vectorial se reduce a notacin de apuntadores; enconsecuencia, aplica lo dicho en la seccin anterior.

    Sin embargo, hay un aspecto que se debe tener en mente: v[i]equivale a (v+i),pero, a diferencia de (p+i), ves una constante de tipo apuntador y, por ende, nose le puede asignar nada. Dicho en otros trminos, cuando se declara un apuntadorp, efectivamente se est declarando una variable que puede contener direcciones;cuando se declara un vector v, se separa espacio en memoria para los elementosque contiene, pero v, como tal, es solo la direccin inicial del vector.Complementariamente, cuando se declara:

    int * p;

    la variable p existe, no as el entero *p; es necesario asignarle algo a p, de locontrario,*pes invlido (no apunta a nada).

    Estructuras

    Las estructuras no constituyen una nueva forma de direccionamiento; se puedenmanejar con los modos vistos hasta ahora. Note que las estructuras son las mismasvariables de siempre, solo que se declaran varias agrupadas bajo un nombre; enconsecuencia, su manejo no difiere mucho del de otras variables, excepto porque sedireccionan con respecto a una direccin base. Por ejemplo, si tenemos laestructura:

    struct {int a;short b;char c;

    } s;

    La estructura como un todo se llama s, lo cual corresponder a una cierta direccinen memoria. La variable a se encuentra a un desplazamiento de cero de esadireccin; la variable b, a un desplazamiento de 4 aes un intde 4 bytesy la c,a 6 bytes:

    Cdigo C Cdigo Ensamblador

    s.a = 1;s.b = 2;s.c = c;

    mov s, 1mov s+4, 2mov s+6, c

    Veamos la misma situacin pero con un apuntador as:7

    7Tenga presente que p->xes lo mismo que (*p).x.

  • 5/21/2018 05 Lenguaje Ensamblador Operaciones(ASM)

    18/29

    38

    Ellenguajeensamblador:operaciones Captulo5.

    Cdigo C Cdigo Ensamblador

    p->a = 1;p->b = 2;p->c = c;

    mov ecx, pmov [ecx], 1mov [ecx+4], 2

    mov [ecx+6], c

    Se usa el direccionamiento indexado, con la direccin base en el registro y eldesplazamiento en la constante.

    El cdigo antes presentado corresponde a lo que realmente se genera en lenguaje demquina. Sin embargo, el ensamblador dispone de una notacin ms cmoda; sedebe tener presente que es solo una notacin, y no corresponde a ningn nuevomodo de direccionamiento. La realidad sigue siendo la antes descrita.

    El acceso a los campos se puede hacer por medio de la notacin:

    mov eax, s1.a

    Se puede combinar con otras notaciones del ensamblador:mov bx, v[esi].bmov [ecx].c, z

    En los dos ltimos casos se presenta una ambigedad; si hubiera varias estructurasdiferentes con un campo llamado c, cmo podra el ensamblador determinar culde ellas se est utilizando? Es necesario que el programador especifique a questructura se est refiriendo, para lo cual existe la sintaxis:

    mov (S ptr [ecx]).c, z

    Recuerde que esta notacin es solo una comodidad, en el fondo, la instruccinanterior sigue siendo: mov [ecx+6], z.

    Expresiones lgicas

    En algunos lenguajes TRUE se representa con 1, y FALSE con cero o algunaconvencin similar. En dichos lenguajes, las expresiones lgicas se puedenevaluar usando las instrucciones lgicas de la mquina de manera parecida a comose calculan las expresiones aritmticas.

    Ahora bien, la situacin es menos clara en un lenguaje como C, puesto que estedefine falso como cero y cierto como cualquier cosa diferente de cero. En el ejemploanterior, si A vale 1 y B vale 2, el and bit a bit dara cero; es decir, falso. Sinembargo, desde el punto de vistas de C, los dos son ciertos, luego el anddebera darcierto. Esto implica que las condiciones lgicas de C no se pueden implementarusando estas instrucciones; en C se calculan usando el flujo de control, aspecto queestudiaremos ms adelante.

    Las expresiones y el registro de indicadores

    Como mencionamos anteriormente, al ejecutar una instruccin, los indicadorespueden ser afectados. Cmo son afectados depende en parte de la instruccin. Engeneral, las operaciones (ADD, SUB, SHR, etc.) afectan los indicadores Sy Zcomo es

  • 5/21/2018 05 Lenguaje Ensamblador Operaciones(ASM)

    19/29

    5.4 Evaluacindeexpresiones 39

    de esperarse: si el resultado es cero, Z= 1; si no, Z= 0. Si es negativo, S= 1; de locontrario,S= 0.

    No todas las instrucciones afectan estos indicadores; en particular, las rotacionesno afectan ni Z, ni S. La instruccin MOVno afecta ningn indicador en absoluto.

    Los dems indicadores no son afectados de una manera estndar y lo mejor esconsultar un manual en caso de duda.

    Veamos el caso particular del indicador de acarreo: las instrucciones de corrimientoSHL, ROR, etc.lo afectan con el bit que expulsan fuera del operando. La adicin,ADD, lo afecta con el acarreo que produce la suma. La resta, SUB, es menosevidente; se podra pensar que basta con hallar el complemento a dos delsubstraendo y sumarlo al minuendo, con lo cual quedara reducido al caso de lasuma. Sin embargo, no es as, puesto que la resta pone en 1 el bit de acarreo si elminuendo es menor que el substraendo, y en cero si no simboliza lo que "se tomprestado".

    5.5 LAS DECLARACIONES

    Para terminar con las expresiones, vamos a estudiar cmo se declaran las variablesen ensamblador. En las secciones siguientes, veremos 4 tipos de entidades quepodemos declarar: escalares, vectores, estructuras y cadenas de caracteres; estasltimas van a ser un tipo derivado de los anteriores.

    Empecemos por describir los identificadores: el primer carcter debe ser una letra,los siguientes pueden ser letras, dgitos o caracteres especiales como $y _. No sepuede usar como identificadores las palabras que se han destinado a otros fines,tales como los nombres de las instrucciones (MOV, ADDetc.) y de los registros (AX,SP, etc.).

    Escalares

    La forma general de una declaracin es:

    Identificador Tipo Valor inicial

    El identificador es el nombre de la variable y sigue las reglas antes explicadas. ElTipo dice cuntos bytes ocupa la variable en cuestin; vamos a utilizar trestamaos,8representados por las palabras:

    BYTE 1 byteWORD 2 bytes

    DWORD 4 bytesEl valor inicial nos permite suponer que, al comenzar la ejecucin del programa,dicha variable ya tiene un valor asignado. La asignacin solamente se hace unanica vez antes de empezar la ejecucin; una vez que esta comienza, el

    8El ensamblador dispone de otros tamaos, pero nosotros solo usaremos estos.

  • 5/21/2018 05 Lenguaje Ensamblador Operaciones(ASM)

    20/29

    4

    Ellenguajeensamblador:operaciones Captulo5.

    programador es responsable de todo lo que ocurra o deje de ocurrir. Comoejemplos, tenemos:

    posicionX WORD 0cambioLinea BYTE 10

    nos definen una variable de 16 bits, con valor inicial 0, llamada posicionX; y unavariable de 8 bits, con valor inicial 10, llamada cambioLinea. El campo de valorinicial puede ser una interrogacin (?), lo cual indica que la variable no tiene unvalor inicial (no sabemos qu contiene cuando empieza la ejecucin).

    Al tener declaraciones, el ensamblador puede verificar que las variables sean bienutilizadas. Por ejemplo, si se tiene:

    a WORD 0mov al, a

    el ensamblador avisar que la variable est siendo mal utilizada (porque el registrono es de tipo palabra). Adems, las declaraciones ayudan a resolver ciertasambigedades; este es el caso de las instrucciones que tienen un solo operandocomo MUL a: sin declaraciones, no sera posible saber si es una multiplicacin de32, 16 o de 8 bits.

    Este mecanismo no es suficiente en ciertos casos v.g.:

    mul [esi]

    Aqu persiste la ambigedad, ya que no sabemos siesiapunta a un dato de 8, 16 32 bits. Para solucionarla, se usa la siguiente notacin: se le antepone al operandoel tipo de datos de la entidad seguido de la palabraptr:

    mul byte ptr [esi]

    mul word ptr [esi]

    Esta construccin tambin nos permite cambiarle el tipo a una variable; porejemplo, tenemos una variable adefinida con WORD, y, por alguna razn, queremoscargar nicamente su parte baja, podemos escribir:

    mov al, byte ptr a

    En este caso, la construccin byte ptrquiere decir "suponga que la variable no esde tipo palabra sino de tipo byte". Tenga en cuenta que este mecanismo notransforma de ninguna manera el contenido de la variable; sencillamente es unaforma de especificar cuntos bytes se deben traer a partir de la direccin de lavariable.

    Vectores

    Para definir un vector es necesario separar espacio para todos los elementos que locomponen. Esto se logra por medio de la construccin:

    Identificador tipo n DUP (c )

    Esta construccin reserva espacio para n elementos del tipo dado. Todos loselementos son inicializados con la constante c. Tenemos, por ejemplo:

  • 5/21/2018 05 Lenguaje Ensamblador Operaciones(ASM)

    21/29

    5.5 Lasdeclaraciones 4

    vectorCaracteres byte 5 dup ( )vectorNumeros word 15 dup (0)matriz word 10 dup ( 5 dup (?) )

    La variable vectorCaracteresdefine un vector de bytes con 5 elementos, dichos

    elementos tienen un valor inicial de blanco (' '). La segunda variable,vectorNumeros, define un vector de 15 posiciones, cada una es una palabra ytodas valen 0 inicialmente. La ltima variable define 50 dobles palabras cuyo valorinicial no est especificado.

    La inicializacin tambin puede ser elemento por elemento:

    vectorCaracteres byte a, b, c, d, e

    esta ltima declaracin es completamente equivalente a:

    vectorCaracteres byte abcde

    Atencin: no es una cadena de caracteres; las cadenas de caracteres no son un tipo

    primitivo en la IA32, sino que toca definirlas (como se ver en una prximaseccin). Esta es sencillamente una notacin para no tener que escribir loscaracteres uno por uno.

    Estructuras

    Este tipo de datos es el equivalente a las estructuras de lenguajes como C. Tambinsirven como base para implementar los objetos. Las declaraciones son de la forma:

    S structa word 0b dword ?c byte ?

    S ends

    La anterior es una estructura, llamada S, con tres campos: el primero de tipopalabra inicializado en 0, el segundo de tipo doble palabra y el ltimo de tipobyte. Esta declaracin no separa espacio en memoria, slo define una estructura enabstracto similar a la declaracin de una estructura en C o de una clase en C++ oJava. Las inicializaciones son los valores por defecto que van a tomar lasentidades declaradas de ese tipo.

    Para separar efectivamente espacio en memoria, se hacen declaraciones de laforma:

    Identificador Tipo {Valor,,Valor }

    DondeIdentificador es el nombre de la variable. Tipo debe haber sido declaradocomo struct. La lista de valores sirve para inicializar los campos de la estructura;si no se pone un valor quiere decir que se debe tomar el valor por defecto el valorque se puso en la definicin destruct.

    Algunos ejemplos de declaracin:

    s1 S {,,}vS S 10 dup ( {,1,} )

  • 5/21/2018 05 Lenguaje Ensamblador Operaciones(ASM)

    22/29

    42

    Ellenguajeensamblador:operaciones Captulo5.

    ss S {1,2,a}, {,1,}, {1,,'b'}

    Cadenas de caracteres

    Las cadenas de caracteres no son un tipo primitivo de datos en la IA32; el softwaredebe definir una representacin. Hay diversas convenciones; aqu usaremos la de C.

    La convencin de C es la siguiente: una cadena de caracteres es una secuencia debytes que termina en el carcter nulo (ASCII NUL, 00H). Por ejemplo, la cadenaHOLA quedara:

    Byte 0 1 2 3 448H 4FH 4CH 41H 00H

    Por esta razn las cadenas de caracteres en C acaban en \0: es una convencin deC para denotar el carcter cuyo cdigoASCIIes 0.

    Para declarar esta misma cadena en ensamblador, haramos lo siguiente:

    c byte H, O, L, A, 0

    Equivalentemente, y ms cmodo:

    c byte HOLA, 0

    Esta cadena se maneja como cualquier vector: con apuntadores o indexamiento.

    Con las cadenas de caracteres es importante diferenciar entre tres conceptos: unacosa es el espacio total asignado para la cadena, otra es cunto ocupa efectivamentey, por ltimo, cuntos caracteres tiene; por ejemplo:

    c byte HOLA, 0, 20 dup (?)

    La cadena tiene los 4 caracteres de HOLA.

    El espacio total ocupado son 5 bytes: los anteriores ms el carcter nulo.

    El espacio asignado para la cadena son 25 bytes: los 5 ya mencionados y 20que no se estn utilizando (todava).

    Procesamiento de las declaraciones

    Las declaraciones de variables son solo una comodidad del ensamblador; lamquina, como tal, solo trabaja con direcciones. Dicho de otra manera: en unprograma ya traducido a lenguaje de mquina no aparecen los identificadores.

    El procesamiento bsico que hace el ensamblador es el siguiente: cuando encuentrauna declaracin, calcula cunto espacio necesita para la entidad y le asigna un sitio

    en la memoria del tamao adecuado. La direccin inicial de esa zona es la direccinasignada a la variable. Posteriormente, cuando encuentra el mismo identificador enuna instruccin, lo reemplaza por la direccin asignada.

    En el caso de las estructuras, cuando el ensamblador encuentra una declaracin,anota los nombres de los campos junto con su desplazamiento con respecto al iniciode la estructura. Cuando el ensamblador encuentra una instruccin que usa algunode los campos, reemplaza el campo por su desplazamiento correspondiente.

    Generacin de apuntadores

  • 5/21/2018 05 Lenguaje Ensamblador Operaciones(ASM)

    23/29

    5.5 Lasdeclaraciones 43

    Las declaraciones son tiles para el programador, pero introducen uninconveniente: puesto que el ensamblador asigna las direcciones, el programadorno sabe dnde quedan localizadas las variables.

    Los apuntadores son direcciones de memoria, y las direcciones son nmeros; en

    consecuencia, si se conoce la direccin, es fcil crear un apuntador: basta conasignar la direccin a un registro. Pero no conocemos las direcciones debido a queel ensamblador se encarga de la traduccin de las etiquetas a nmeros.

    El ensamblador provee un mecanismo para que se puedan recuperar las direccioneslo cual sirve permite generar apuntadores; se trata del operador offset:

    mov eax, offset x

    eaxqueda apuntando a x. Este es un operador del ensamblador, no de la mquina.El ensamblador se encarga de reemplazar la expresin offset xcon la direccinde x. Esto implica, en particular, que el movanterior es de constante a registro: elensamblador reemplaza offset xcon la direccin de x, la cual es una constante.

    Hay otro mecanismo de generar apuntadores, este s basado en una instruccin demquina: la instruccin lea(Load Effective Address). Esta instruccin tiene elmismo formato que un mov, pero en lugar de cargar en el operando destino el valordel operando fuente, carga su direccin. As, la instruccin:

    lea eax, x

    tambin deja eaxapuntando a x.

    Los dos mecanismos no son completamente equivalentes: offset sirve paravalores estticos, mientras que lea sirve para valores dinmicos. Por ejemplo, elsiguiente apuntador no se puede crear con offset:

    lea eax, v[esi]

    Cuando se est ensamblando el programa, no se sabe el valor de eside hecho,puede cambiar dinmicamente en ejecucin, luego no se puede saber cul es ladireccin de v[esi]; esto solo se puede determinar en ejecucin.Complementariamente, la siguiente declaracin solo se puede hacer conoffset:

    p dword offset x

    pes una variable que queda inicializada con un apuntador ax.

    EJERCICIOS1- Programacin mixta. Escriba un programa en C que declara una variable de

    tipo short inty una de tipo char; despus escriba el siguiente cdigo enlnea en ensamblador:

    a- Asigne los siguientes nmeros a la variable de tipo short int eimprmalos en hexadecimal en la pantalla (esta ltima accin en C). Comparelos resultados.

  • 5/21/2018 05 Lenguaje Ensamblador Operaciones(ASM)

    24/29

    44

    Ellenguajeensamblador:operaciones Captulo5.

    A5H, 165, 10101001B, 10, -10, 0, -0, 32767, -32768, 65535.

    b-Asigne los siguientes nmeros a la variable de tipo chare imprmalos enhexadecimal en la pantalla (esta ltima accin en C). Compare los resultados.

    41H, 'A', 65, 01000001B, 127, 128, 255, -128, -1, 0.

    c- Asigne las siguientes parejas de nmeros a ah y al, respectivamente,despus asigne ax a la variable de tipo short int e imprmalos enhexadecimal en la pantalla (esta ltima accin en C).

    15 y 1, 'A' y 'B', 41H y 42H, -1 y -1.

    2- Indique cules de los siguientes direccionamientos son correctos:

    Instruccin Correcto?mov esi, [esi+1]

    mov esi, esi+1

    sub [esi], [edi + ebx]

    add esi, [edi + edx]mov ax, var + 1

    mov esi, [esi + 2] - esi

    or ebx, [ebp - 2]

    mov [esi], 4

    mov 4, [esi]

    mul [esi + ebx + ebp]

    and ax, [esi - ebx]

    3- En un programa se tienen las siguientes declaraciones:

    v word 3815H, A3B5H, 26F7H, 4855H, 0666Hb byte 10, 20, 30, 40, CABE

    a-Qu queda en axdespus de ejecutar cada uno de los siguientes grupos deinstrucciones?

    Cdigo ax =mov esi, 4mov ax, v[esi]

    mov esi, 3mov ax, v[esi]

    mov esi, 10mov ax, v[esi]

    b-Qu queda enALdespus de ejecutar cada uno de los siguientes grupos deinstrucciones?

    Cdigo al =mov esi, 0mov al, b[esi]

    mov esi, 5mov al, b[esi]

    mov esi, 8mov al, b[esi]

  • 5/21/2018 05 Lenguaje Ensamblador Operaciones(ASM)

    25/29

    Captulo5. Ejercicios 45

    4- En los ejercicios que siguen, se da un segmento de cdigo en C y 4 segmentosde cdigo en ensamblador; diga cul de ellos es equivalente al segmento en C(si varios lo son, diga cul es mejor y por qu).

    a-int a, b;

    a = b;1. 2. 4. 3.

    mov a, b mov eax, bmov a, eax

    mov ax, bmov a, ax

    mov b, eaxmov eax, a

    b-char a, v[5]; int i;a = v[i];

    1. 2. 4. 3.mov eax, v[i]mov a, eax

    mov ch, imov ah, v[ch]mov a, ah

    mov ecx, i

    mov eax,v[ecx]

    mov a, eax

    mov ecx, i

    mov ah, v[ecx]

    mov a, ah

    c-int a, i, v[5];a = v[i];

    1. 2. 4. 3.mov eax, v[i]mov a, eax

    mov ecx, imov eax,v[4*ecx]mov a, eax

    mov ecx, imov eax, v[ecx]mov a, eax

    mov eax, v[4*i]mov a, eax

    d-short a[4], b; short *p = a;p++; b = *p;

    1. 2. 4. 3.add p, 2mov eax, p

    mov ebx,[eax]mov a, ebx

    add p, 2mov bx, [p]

    mov a, bx

    add p, 2mov eax, p

    mov bx, [eax]mov a, bx

    mov eax, padd eax, 2

    mov bx, [eax]mov a, bx

    e-unsigned short a; int b;b = a;

    1. 2. 4. 3.mov edx, amov b, edx

    mov dx, amov b, dx

    mov edx, 0mov dx, amov b, edx

    mov b, 0mov dx, amov b, dx

    5- Una forma de calcular el cuadrado de un nmero que se encuentra eneaxes:muleax

    a-Si se sabe que en eaxhay un natural funciona este mtodo?b-Si en eaxhay un entero funciona?

    6- Dadas las declaraciones mostradas, escriba en ensamblador la evaluacin delas siguientes expresiones (trate de optimizar los clculos):

    int a, b, c, d, e, f;char x, y;

    Expresin

  • 5/21/2018 05 Lenguaje Ensamblador Operaciones(ASM)

    26/29

    46

    Ellenguajeensamblador:operaciones Captulo5.

    (a + b)*(a + c)*(a + d)

    (a + b)*(c - d) + (a + b)* (e + f)

    (a + b)*(c - d) + (a + b)* (c + d)

    a - - b

    x + y

    x ax * y

    x + a

    7- En el registro al se tiene un dgito- carcter (0 a 9) codificado en ASCII.Calcule su valor numrico (0 a 9) y djelo enalmismo.

    8- Dadas las declaraciones mostradas, analice las siguientes instrucciones de C;diga si compilan, y, si es as, tradzcalas a ensamblador.

    int a, b;char x;char * p = &x, *q;

    Expresin Compila?a = b++;

    a = a++;

    p+1 = q + 1;

    *(p+1) = *(q+1);

    q = p++;

    *p++ = 5;

    (*p)++ = a;

    (*(++q))++;

    q = *p++;

    p++ = q;

    9- Dadas las declaraciones mostradas, analice las siguientes instrucciones de C;diga si compilan, y, si es as, tradzcalas a ensamblador.

    int a, i, j;int v[100];int * p, *q;

    Expresin Compila?v[6] = v[i];

    v[i] += a;

    p = v + i;

    v = p + i;

    *p = *(v + i);

    *v = *(p + i);p[i] = a;

    v[j] = a*(v[i] + v[j]);

    a = v[v[i]];

    p = 3*q;

    10- Se tiene la siguiente declaracin para un vector:

    v byte 100 dup (?)

  • 5/21/2018 05 Lenguaje Ensamblador Operaciones(ASM)

    27/29

    Captulo5. Ejercicios 47

    a- Escriba cdigo en ensamblador para generar un apuntador a v[i];i esuna variable entera (de tipo dword). El apuntador se debe dejar en eax.

    b-Repita el problema anterior con un vector de dobles palabras (dword).

    c-Repita el problema anterior con un vector de elementos de tamao t.

    11- Se tiene la siguiente declaracin para una matriz:

    m byte 100 dup ( 200 dup (?) )

    a-Escriba cdigo en ensamblador para generar un apuntador am[i][j]; iyjson variables enteras (de tipo dword). El apuntador se debe dejar en eax.

    b-Repita el problema anterior con una matriz de dobles palabras (dword).

    c-Repita el problema anterior con una matriz de elementos de tamao t.

    d-Se tiene una matriz representada en un vector de apuntadores a vectores.Repita las partes a- a c- con esta representacin.

    12- Se tienen cadena de caracteres representadas con convenciones de C.a- Una forma de representar un vector de cadenas de caracteres es reservarun espacio mximo para cada cadena. Por ejemplo, el vector que se muestra acontinuacin, tiene tres cadenas cada una con 8 bytes disponibles (pero nonecesariamente usados):

    Las posiciones marcadas con "?" no estn ocupadas.

    - Se tiene un apuntador p al comienzo del vector, escriba cdigo enensamblador para que quede apuntando al i-simo elemento (i es unavariable entera).

    - Escriba cdigo en ensamblador para poner un blanco en la posicinjde la i-sima cadena (iy json variables enteras).

    b-Otra forma de representar vectores de cadenas es por medio de un vectorde apuntadores a las cadenas. En este caso, solo se reserva el mnimo espaciorequerido por cada cadena:

    Repita el punto anterior con esta representacin.

    13- Se tiene la declaracin:

    S structx word ?

    s o l o 0H e j e m p l o 0H u n 0H

    V

    s o l o 0H ? ? ? u n 0H ? ? ? ? ? e j e m p l o 0HPosicin 0 Posicin 1 Posicin 2

  • 5/21/2018 05 Lenguaje Ensamblador Operaciones(ASM)

    28/29

    48

    Ellenguajeensamblador:operaciones Captulo5.

    y dword ?z byte 3 dup (?)

    S ends

    Hay dos variables de tipo S llamadas ry t, y un vector de estructuras de tipoSllamado vs. Traduzca las siguientes asignaciones a ensamblador:

    Instruccina =r.x;

    r.x = a;

    r.y = t.y;

    r.z[j] = c;

    r = t;

    a = vs[i].x;

    vs[i].y = vs[j].y;

    vs[i].z[j] = c;

    vs[i] = vs[j];

    p1 = &vs[i];

    p2 = &vs[i].y;p3 = &vs[i].z[j];

    14- Se dispone de una lista encadenada compuesta por estructuras de la forma:

    Nodo structvalor byte ?siguiente dword ?

    Nodo ends

    siguiente es un apuntador al prximo elemento. La informacin del nodoest almacenada en valor. La variable cabeza tiene un apuntador alprincipio de la lista. Traduzca las siguientes asignaciones:

    Instruccina = (*cabeza).valor;(*cabeza).valor = a;

    cabeza = (*cabeza).siguiente;

    15- Escriba cdigo en ensamblador para calcular (eax mod 4), sin hacerdivisiones. Generalice a (eax mod 2n).

    16- Escriba un programa que recibe en eax un nmero y lo convierte, sobre eaxmismo, en 1 0 dependiendo de si es impar o par.

    17- Suponiendo que eax vale 1 0, escriba un programa que pone el valor deeax en el primer bit de ebx sin modificar los otros bits de ebx.

    18- Una funcin lgica de tres variables tiene 8 casos posibles. Estos 8 casos sepueden codificar en un byte, por ejemplo en dl, de la siguiente maneraf(0,0,0) = bit0 de dl, f(0,0,1) = bit1 de dl,etc. Suponiendo que eax, ebx yecxvalen 0 1, calculef(eax, ebx,ecx).

    19- Se tiene un nmero en eax y se quiere activar los indicadores para saber sidicho nmero es cero, negativo etc. Cmo se puede hacer esto sin daar elvalor que se encuentra eneax?

  • 5/21/2018 05 Lenguaje Ensamblador Operaciones(ASM)

    29/29

    Captulo5. Ejercicios 49

    20- Como vimos anteriormente, en el cdigoASCII, los caracteres se almacenan enun byte pero slo usan 7 bits. El 8 bit se puede utilizar para guardar un bit deparidad.

    Suponiendo que se tiene un carcter en al, escriba un programa que calcula

    el bit de paridad para dicho carcter y lo almacena en el octavo bit de al.Hay una instruccin, lahf, que copia algunos bits del registro de indicadoresen ah: signo (S) en el bit 7, cero (Z) en el 6, acarreo auxiliar (A) en el 4,paridad (P) en el 2 y acarreo (C) en el bit 0 los bits 5,3 y 1 de ahquedanindefinidos.

    21- Se tiene un vector de bits como el del ejercicio 4.9.

    a- Escriba un programa en ensamblador para obtener el i-simo bit delvector. El valor del bit (1 0) debe quedar eneax.

    b-Escriba un programa para modifica el i-simo bit del vector sin modificar

    los otros. El programa dispone de la posicin del bit que se quiere modificaren una variable entera, y, en otra, del valor que se quiere poner (1 0).

    22- Se quiere manejar nmeros de 3 bytes. Los nmeros se almacenan envariables del estilo:

    n byte 3 dup(?)

    El formato de los nmeros es little endian byte menos significativo a laizquierda.

    a-Desarrolle cdigo en ensamblador para leer un nmero de 3 bytes eneax.

    b-Desarrolle cdigo en ensamblador para escribir un nmero de 3 bytes que

    se encuentra en eaxen una variable de 3 bytes en memoria.23- Se tiene un subvector representado con las convenciones del ejercicio 4.35.

    Escriba un programa en ensamblador para obtener el i-simo elemento delsubvector.

    24- Se tiene un subvector representado con las convenciones del ejercicio 4.36.Escriba un programa en ensamblador para obtener el i-simo elemento delsubvector.

    25- Se tiene un vector disperso representado con las convenciones del ejercicio4.37. Escriba un programa en ensamblador para obtener el i-simo elementodel vector.