Está en la página 1de 9

2.

3 Instrucciones básicas, de transferencia de datos y aritméticas


En el lenguaje ensamblador, uno debe estar al pendiente del almacenamiento de datos y los
detalles específicos de la máquina, lo que significa que los ensambladores proporcionan una
tremenda libertad cuando se declaran y se mueven datos. Realizan muy poca comprobación de
errores.

2.3.1 Tipos de operandos


Ahora veremos tres tipos de operandos de instrucciones: inmediatos, de registro y de
memoria.
La siguiente tabla presenta una notación simple para los operandos, adaptada de los manuales
de la familia IA-32 de Intel.

Notación de operandos de instrucciones.

Registros de uso general

• AX: Acumulador (AL:AH)


• BX: Registro base (BL:BH)
• CX: Registro contador (CL:CH)
• DX: Registro de datos (DL:DH)

Registros de segmento (Solo se pueden usar para los usos mencionados a excepción de ES)

• DS: Registro del segmento de datos


• ES: Registro del segmento extra
• SS: Registro del segmento de pila
• CS: Registro del segmento de código
Registros punteros (También pueden tener uso general)

• BP: Registro de apuntadores base


• SI: Registro índice fuente
• DI: Registro ìndice destino

Registros especiales (Solo se pueden usar para los usos mencionados)

• SP: Registro apuntador de la pila


• IP: Registro apuntador de la siguiente instrucción
• F: Registro de banderas (8 bits)

2.3.2 Instrucción MOV


La instrucción MOV copia datos de un operando de origen a un operando de destino. Esta
instrucción, conocida como transferencia de datos. Su formato es:

MOV destino, origen y es equivalente a destino = origen;

MOV es bastante flexible en el uso de sus operandos, siempre y cuando se observen las siguientes
reglas:

• Ambos operandos deben ser del mismo tamaño.


• Ambos operandos no pueden ser operandos de memoria.
• CS, EIP e IP no pueden ser operandos de destino.
• Un valor inmediato no puede moverse a un registro de segmento.

He aquí una lista de las variantes generales de MOV, excluyendo los registros de segmento:

MOV reg, reg


MOV mem, reg
MOV reg, mem
MOV mem, imm
MOV reg, imm

Memoria a memoria: Una sola instrucción MOV no puede usarse para mover datos
directamente de una ubicación de memoria a otra. En vez de ello, puede mover el valor del
operando de origen a un registro, antes de mover su valor a un operando de memoria:
.data
var1 WORD ?

var2 WORD ?
.code
mov ax,var1
mov var2,ax
2.3.3 Operandos de desplazamiento directo
Para crear un operando de desplazamiento directo podemos sumar un desplazamiento al nombre
de una variable. Esto nos permite acceder a ubicaciones de memoria que tal vez no tengan
etiquetas explícitas. Empecemos con un arreglo de bytes llamado arregloB:

arregloB BYTE 10h, 20h, 30h, 40h, 50h

Si utilizamos MOV con arregloB como el operando de origen, moveremos de manera automática
el primer byte en el arreglo:
mov al,arregloB ; AL = 10h

Podemos acceder al segundo byte en el arreglo, sumando 1 al desplazamiento de arregloB:

mov al,[arregloB+1] ; AL = 20h

Para acceder al tercer byte, le sumamos 2:


mov al,[arregloB+2] ; AL = 30h

Al encerrar una dirección efectiva entre corchetes, indicamos que la expresión se utiliza para
hacer referencia a una dirección de memoria para obtener su contenido. MASM no requiere los
corchetes, por lo que las siguientes instrucciones son equivalentes:
mov al, [arregloB+2]
mov al, arregloB+2

Comprobación de rango MASM no tiene comprobación de rango integrada para las direcciones
efectivas. Si ejecutamos la siguiente instrucción, el resultado es un traicionero error lógico, por
lo que debemos ser muy cuidadosos al comprobar las referencias a arreglos:

mov al, [arrebloB+20] ; AL = ??


Arreglos tipo palabra y doble palabra En un arreglo de palabras de 16 bits, el desplazamiento
de cada elemento del arreglo es 2 bytes más adelante del anterior. Ésta es la razón por la cual
sumamos 2 a arregloW en el siguiente ejemplo, para llegar al segundo elemento:
.data
arregloW WORD 100h,200h,300h
.code
mov ax, arregloW ; AX = 100h
mov ax, [arregloW+2] ; AX = 200h

De manera similar, el segundo elemento en un arreglo tipo doble palabra se encuentra a 4 bytes
más adelante del primero:
.data
arregloD DWORD 10000h,20000h
.code
mov eax, arregloD ; EAX = 10000h
mov eax, [arregloD+4] ; EAX = 20000h
2.3.6 Suma y resta
La aritmética es un tema bastante extenso en el lenguaje ensamblador, por lo que lo dividiremos
en pasos. Primero nos enfocaremos en la suma y resta de enteros y más adelante estudiaremos
la multiplicación y división de enteros.

2.3.6.1 Instrucciones INC y DEC


Las instrucciones INC (incremento) y DEC (decremento) suman 1 y restan 1 de un solo
operando. La sintaxis es:
INC reg/mem
DEC reg/mem

A continuación se muestran algunos ejemplos:


.data
miPalabra WORD 1000h
.code
inc miPalabra ; 1001h
mov bx, miPalabra
dec bx ; 1000h

Las banderas Desbordamiento, Signo, Cero, Acarreo auxiliar y Paridad cambian de acuerdo al
valor del operando de destino. No afectan a la bandera Acarreo (lo cual es un poco sorprendente).

2.3.6.2 Instrucción ADD


La instrucción ADD suma un operando de origen con uno de destino del mismo tamaño. La
sintaxis es:
ADD dest, origen
Origen permanece sin cambio en la operación, y la suma se almacena en el operando de destino.
He aquí un ejemplo que suma dos enteros de 32 bits:

.data
var1 DWORD 10000h
var2 DWORD 20000h
.code
mov eax,var1 ; EAX = 10000h
add eax,var2 ; EAX = 30000h

Banderas Las banderas Acarreo, Cero, Signo, Desbordamiento, Acarreo auxiliar y Paridad cambian
de acuerdo con el valor del operando de destino.

2.3.6.3 Instrucción SUB


La instrucción SUB resta un operando de origen a un operando de destino. La sintaxis es:

SUB dest, origen

He aquí un ejemplo breve de código que resta dos enteros de 32 bits:

.data
var1 DWORD 30000h
var2 DWORD 10000h
.code
mov eax, var1 ; EAX = 30000h
sub eax, var2 ; EAX = 20000h
Una manera sencilla de realizar una resta sin tener que crear nuevos circuitos digitales es negar
y después sumar. Por ejemplo, 4- 1 puede interpretarse como 4+ (-1). Para los números
negativos se utiliza la notación de complementos a dos, por lo que 1 se representa mediante
11111111:

Banderas: Las banderas Acarreo, Cero, Signo, Desbordamiento, Acarreo auxiliar y Paridad
cambian de acuerdo con el valor del operando de destino.

2.3.6.4 Instrucción imul


2.3.6.4 Instrucción idiv
2.3.6.4 Instrucción NEG
La instrucción NEG (negación) invierte el signo de un número, convirtiéndolo en su complemento
a dos. Se permiten los siguientes operandos:

NEG reg
NEG mem

(Recuerde que para encontrar el complemento a dos de un número se invierten todos los bits en
el operando de destino y se le suma 1).

Banderas Las banderas Acarreo, Cero, Signo, Desbordamiento, Acarreo auxiliar y Paridad
cambian de acuerdo con el valor del operando de destino.

2.3.6.5 Implementación de expresiones aritméticas


Habiendo estudiado las instrucciones ADD, SUB y NEG, tiene los medios para implementar
expresiones aritméticas que involucran la suma, resta y negación en lenguaje ensamblador. En
otras palabras, uno puede simular lo que un compilador en C++ podría hacer al leer una expresión
tal como:

valR = -valX + (valY – valZ);

Se utilizarán las siguientes variables de 32 bits:

valR SDWORD ?
valX SDWORD 26
valY SDWORD 30
valZ SDWORD 40

Al traducir una expresión, evalúe cada término por separado y combine los términos al final.
Primero, negamos una copia de valX:

; primer término: -valX


mov eax,valX
neg eax ; EAX = -26

Después, valY se copia a un registro y se resta valZ: segundo término: (valY – valZ)
mov ebx,valY
sub ebx,valZ ; EBX = -10

Por último, se suman los dos términos (en EAX y EBX):


; se suman los términos y se almacenan:
add eax,ebx
mov valR,eax ; -36

También podría gustarte