04.06.2013 Views

PRÁCTICA 13

PRÁCTICA 13

PRÁCTICA 13

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

LENGUAJE ENSAMBLADOR 80386 <strong>PRÁCTICA</strong> <strong>13</strong><br />

AUTOR: PROFESOR SALVADOR SAUCEDO FLORES<br />

EDICIÓN: PROFESOR PABLO FUENTES RAMOS<br />

<strong>PRÁCTICA</strong> <strong>13</strong><br />

SUMA, RESTA, MULTIPLICACIÓN Y DIVISIÓN DE DOS NÚMEROS<br />

REALES DE PUNTO FLOTANTE DE PRECISIÓN SENCILLA, SEGÚN<br />

NORMA IEEE-754<br />

1 INTRODUCCIÓN<br />

Mediante esta práctica trabajaremos con números reales de precisión<br />

sencilla, según el estándar IEEE-754 y haremos las operaciones básicas de<br />

suma, resta, multiplicación y división de dos números de punto flotante,<br />

necesitándose por fuerza de un microprocesador 80386 o más reciente que<br />

cuente con coprocesador matemático.<br />

2 OBJETIVOS<br />

Al término de esta práctica el alumno podrá:<br />

2.1 Trabajar con rutinas aritméticas que usan el procesador numérico.<br />

2.2 Realizar operaciones básicas y exhibir el resultado<br />

2.3 Hacer que un programa revise si el procesador numérico está disponible<br />

3 DESARROLLO<br />

3.1 Capturar los siguientes los siguientes cuatro módulos, ensamblarlos<br />

y meterlos a la librería PF.<br />

%TITLE “INICIA87.ASM INICIALIZA EL PROCESADOR NUMÉRICO 80387”<br />

; Ensamblar y poner en librería PF.LIB<br />

;<br />

; Llamar con: AX = palabra de control para fijar redondeo, modo, bits de precisión, máscara de excepciones<br />

;<br />

; Retorna: (si el coprocesador está presente) bandera ZF = puesta (1)<br />

;<br />

; (Si coprocesador no hallado) ZF = falsa (0)<br />

;<br />

; Destruye: nada<br />

IDEAL<br />

MODEL small<br />

<strong>13</strong>-1


LENGUAJE ENSAMBLADOR 80386 <strong>PRÁCTICA</strong> <strong>13</strong><br />

codeseg<br />

PUBLIC Inicia87<br />

PROC Inicia87<br />

push bx ax ;salva registros<br />

mov ax,-1 ;pone FFFFH en la pila<br />

push ax<br />

mov bx,sp ;la hace direccionable<br />

fninit ;trata de inicializar el coprocesador<br />

fnstsw [ss:bx] ;trata de traer palabra de estado<br />

pop ax ;si 8 bits bajos son cero,<br />

or al,al ;el coprocesador está presente<br />

jnz @@10 ;salta si no hay coprocesador<br />

fldcw [ss:bx+2] ;carga al coprocesador la palabra de control<br />

@@10:<br />

pop ax bx ;restaura registros<br />

ret ;y regresa el resultado en la bandera Z<br />

ENDP Inicia87<br />

end<br />

%TITLE “FALOG.ASM CALCULA ANTILOG COMÚN EN 80387”<br />

;<br />

; FALOG.ASM calcula el antilogaritmo en 80387<br />

;<br />

; Llamar con: ST(0) = argumentos<br />

;<br />

; Retorna: ST(0) = antilogaritmo de base 10<br />

;<br />

; Usa: registros del CPU se preservan, usa tres celdas de la pila del coprocesador<br />

;<br />

; Nota: Para obtener antilogaritmo natural, reemplazar “fldl2t” con la instrucción “fldl2e”.<br />

;<br />

; Estar seguro que el coprocesador ha sido iniciado con un llamado previo a INICIA87!<br />

IDEAL<br />

MODEL small<br />

Codeseg<br />

vieja equ [word bp-4] ;palabra original de control<br />

nueva equ [word bp-2] ;palabra nueva de control<br />

PUBLIC falog<br />

PROC falog<br />

push ax ;salva registros y<br />

push bp ;forma apuntador<br />

mov bp,sp ;para variables locales<br />

AUTOR: PROFESOR SALVADOR SAUCEDO FLORES<br />

EDICIÓN: PROFESOR PABLO FUENTES RAMOS<br />

<strong>13</strong>-2


LENGUAJE ENSAMBLADOR 80386 <strong>PRÁCTICA</strong> <strong>13</strong><br />

sub sp,4<br />

fldl2t ;carga log2(10)<br />

fmulp st(1),st(0) ;log2(10) * argumento<br />

fld st(0) ;duplica el producto<br />

fstcw vieja ;trae palabra vieja de control<br />

fwait ;espera<br />

mov ax,vieja ;cambia modo de redondeo<br />

and ax,0f3ffh ;a “hacia abajo”<br />

or ax,0400h<br />

mov nueva,ax<br />

fldcw nueva ;fija modo de redondeo<br />

frnint ;trae parte entera del producto<br />

fldcw vieja ;restaura modo original de redondeo<br />

fld st(0) ;duplica parte entera<br />

fxch st(2) ;trae producto original<br />

fsubrp st(1),st(0) ;halla parte fraccional<br />

fld1<br />

fchs<br />

fxch st(1) ;escala parte fraccional<br />

fscale<br />

fstp st(1) ;descarta basura del coprocesador<br />

f2xm1 ;eleva 2 a la -1<br />

fld1<br />

faddp st(1),st(0) ,corrige por el -1<br />

fmul st(0),st(0) ;hace resultado al cuadrado<br />

fscale ;escala por parte entera<br />

fstp st(1) ;tira basura del coprocesador<br />

add sp,4 ;descarta variables locales<br />

pop bp ;restaura registros y<br />

pop ax ;retorna resultado en ST(0)<br />

ret<br />

ENDP falog<br />

end ;fin de módulo FALOG.ASM<br />

%TITLE “ATOF – CONVERSIÓN DE ASCII A BINARIO DE PUNTO FLOTANTE”<br />

; Ensamblarlo y ponerlo en librería PF<br />

;<br />

; ATOF.ASM Convierte cadena ASCII a número binario de punto flotante en la pila de 80387<br />

; (También requiere FALOG en FALOG.ASM<br />

;<br />

; Llamar con DS:DI = dirección de ka cadena con la forma<br />

; [signo][digitos][.[digitos]][E\e[signo][exp]] se ignoran espacios y tabuladores delanteros<br />

;<br />

; Retorna: ST(0) = valor binario en punto flotante DS:SI = dirección+1 del terminador<br />

;<br />

; Usa: nada<br />

;<br />

; Esta rutina no advierte en el caso de que haya sobre flujo y termina con el primer<br />

; carácter no valido<br />

; Asegurarse de que el 80387 ha sido previamente iniciado con una llamada previa a INICIA87!<br />

blanco equ 20h ;ASCII de carácter blanco<br />

AUTOR: PROFESOR SALVADOR SAUCEDO FLORES<br />

EDICIÓN: PROFESOR PABLO FUENTES RAMOS<br />

<strong>13</strong>-3


LENGUAJE ENSAMBLADOR 80386 <strong>PRÁCTICA</strong> <strong>13</strong><br />

tab equ 09h ;ASCII de carácter tabulador<br />

IDEAL<br />

MODEL small<br />

dataseg<br />

Int10 dw 10 ;constante entera 10<br />

Digito dw 0 ;dígito convertido actual<br />

Lugares dw 0 ;número de lugares decimales<br />

codeseg<br />

EXTRN falog:near ;se necesita la rutina FALOG<br />

PUBLIC atof<br />

PROC atof ;ASCII a punto flotante<br />

push ax cx dx ;salva registros<br />

call convierte ;convierte la mantisa<br />

neg dx ;salva -1 * lugares decimales<br />

mov [lugares],dx<br />

or al,20h ;mantiene carácter para minúsculas<br />

cmp al,’e’ ;¿está el exponente presente?<br />

je @@10 ;si, salta<br />

fldz ;asume exponente cero<br />

jmp @@20<br />

@@10:<br />

call convierte ;convierte exponente<br />

@@20:<br />

fiadd [lugares] ;ajusta exponente para dec. lugares en mantisa<br />

call falog ;eleva a la potencia 10<br />

fmul ;exponente * mantisa<br />

pop dx cx ax ;restaura registros<br />

ret ;retorna ST(0) = resultado<br />

ENDP atof<br />

;<br />

; CONVIERTE: Llamada por ATOF para convertir un número ASCII con posible signo y/0 punto decimal<br />

; Entrada: DS:SI = dirección de la cadena<br />

; Retorna: ST(0) = resultado<br />

; AL = primer carácter no convertible<br />

; DX = número de dígitos tras el punto decimal<br />

; DS:SI = dirección +1 del carácter en AL<br />

; Usa: AH,CX<br />

;<br />

PROC convierte ;convierte campo numérico<br />

fldz ;inicializa resultado<br />

xor cx,cx ;inicializa signo<br />

AUTOR: PROFESOR SALVADOR SAUCEDO FLORES<br />

EDICIÓN: PROFESOR PABLO FUENTES RAMOS<br />

<strong>13</strong>-4


LENGUAJE ENSAMBLADOR 80386 <strong>PRÁCTICA</strong> <strong>13</strong><br />

mov dx,-1 ;inicializa conteo decimal<br />

@@10:<br />

lodsb ;elimina espacios<br />

cmp al,blanco ;ignora blancos delanteros<br />

je @@10<br />

cmp al,tab ;ignora tabuladores delanteros<br />

je @@10<br />

cmp al,’+’ ;verifica si un + precede<br />

je @@20 ;si, salta<br />

cmp al,’-‘ ;¿es el símbolo -?<br />

jne @@30 ;no, prueba si numérico<br />

dec cx ;si, pone bandera<br />

@@20:<br />

lodsb ;trae siguiente carácter<br />

@@30:<br />

cmp al,’0’ ;¿es carácter válido?<br />

jb @@40 ;salta si no ‘0’ a ‘9’<br />

cmp al,’9’<br />

ja @@40 ;salta si no ‘0’ a ‘9’<br />

and ax,0fh ;aísla cuatro bits bajos<br />

mov [digito],ax ;y salva valor del dígito<br />

fimul [int10] ;valor previo * 10<br />

fiadd [digito] ;acumula nuevo dígito<br />

or dx,dx ;¿pasó punto decimal?<br />

js @@20 ;no, convierte siguiente dígito<br />

inc dx ;si, cuenta dígitos<br />

jmp @@20 ;convierte siguiente dígito<br />

@@40:<br />

cmp al,’.’ ;¿es el punto decimal?<br />

jne @@50 ;no, proceder<br />

inc dx ;indica punto decimal hallado<br />

jmp @@20 ;convierte más dígitos<br />

@@50:<br />

jcxz @@60 ;salta si resultado positivo<br />

fchs ;hace resultado negativo<br />

@@60:<br />

or dx,dx ;¿halló punto decimal?<br />

jns @@70 ;si, salta<br />

xor dx,dx ;retorna cero lugares<br />

@@70:<br />

ret ;retorna ST(0) = resultado<br />

ENDP convierte<br />

end ;fin de módulo ATOF.ASM<br />

AUTOR: PROFESOR SALVADOR SAUCEDO FLORES<br />

EDICIÓN: PROFESOR PABLO FUENTES RAMOS<br />

<strong>13</strong>-5


LENGUAJE ENSAMBLADOR 80386 <strong>PRÁCTICA</strong> <strong>13</strong><br />

%TITLE “FTOA – PUNTO FLOTANTE A ASCII”<br />

; Ensamblarlo y ponerlo en librería PF<br />

;<br />

; FTOA.ASM – Convierte binario de punto flotante<br />

; Número real en la pila del 80387 Stack en ASCII (usa FALOG de FALOG.ASM)<br />

;<br />

; Llamar con ST(0) = número de punto flotante<br />

; DS:DI = área para recibir cadena<br />

;<br />

; Retorna: DS:SI = dirección de cadena convertida<br />

; AX = largo de la cadena<br />

; Pila del coprocesador “sube”<br />

;<br />

; Usa: nada<br />

;<br />

; Asegurarse de que el coprocesador ha sudo iniciado adecuadamente con una llamada previa a INICIA87!<br />

IDEAL<br />

MODEL small<br />

dataseg<br />

signo dw 0 ;recibe estado FXAM<br />

viejo dw 0 ;modo de redondeo previo<br />

nuevo dw 0 ;nuevo modo de redondeo<br />

exp dw 0 ;potencia de 10<br />

status dw 0 ;recibe estado ICOM<br />

mant dt ;mantisa como valor BCD<br />

fp<strong>13</strong>17 dq 1,0e17 ;constante para escalamiento<br />

fp1e18 dq 1,0e18 ;constante para escalamiento<br />

int10 dw 10 ;constante par escalamiento<br />

CadOp db ‘+0.000000000000000000E+000’ ;exhibido si<br />

LonOp equ offset CadOn-offset CadOp ;ST(0) = +0<br />

CadOn db ‘-0.000000000000000000E+000’ ;exhibido si<br />

LonOn equ offset CadIp-offset CadOn ;ST(0) = -0<br />

CadIP db ‘’ ;exhibido si<br />

LonIP equ offset CadIn-offset CadIp ;es infinito positivo<br />

CadIN db ‘’ ;exhibido si ST(0)<br />

LonIN equ offset CadNatN-offset CadIN ;es infinito negativo<br />

CadNaN db ‘’ ;exhibido si ST(0)<br />

LonNaN equ offset CadAn-offset CadNaN ;contiene Not-A-Número<br />

CadAn db ‘’ ;exhibido para anormales<br />

LonAn equ offset CadDe-offset CadAn ;positivos y negativos<br />

CadDe db ‘’ ;exhibido para denormales<br />

LonDe equ offset CadVac-offset CadDe ;positivos o negativos<br />

CadVac db ‘’ ;exhibido si ST(0’)<br />

LonVac equ offset Tipofin-offset CadVac ;está marcado vacío<br />

AUTOR: PROFESOR SALVADOR SAUCEDO FLORES<br />

EDICIÓN: PROFESOR PABLO FUENTES RAMOS<br />

<strong>13</strong>-6


LENGUAJE ENSAMBLADOR 80386 <strong>PRÁCTICA</strong> <strong>13</strong><br />

Tipofin db 0<br />

codeseg<br />

EXTRN falog:near ;se usa rutina FALOG<br />

PUBLIC ftoa<br />

PROC ftoa ;punto flotante a ASCII<br />

push bx dx cx di es ;salva registros<br />

push ds ;hace que DS apunte a @data<br />

pop es<br />

fxam ;prueba tipo de número<br />

fstsw ;salva estado de FXAM<br />

fwait<br />

mov bx,[signo] ;retira estado y<br />

and bx,4700h ;aísla C3, C2, C1, C0<br />

rol bx,1 ;para formar un<br />

rol bx,1 ;con valor de 0-15, y luego<br />

shl bh,3 :*2 para formar índice de asalto<br />

rol bx,3<br />

shl bx,1<br />

jmp [cs: TipoTab+bx] ;salta según tipo de número<br />

@@10:<br />

fabs ;forza un número positivo<br />

fxtract ;extrae exponente<br />

fxch st(1) ;pone exponente encima<br />

fldlg2 ;forma potencia de 10<br />

fmulp st(1),st(0)<br />

fstcw [viejo] ;salva modo de redondeo actual<br />

fwait<br />

mov ax,[viejo] ;hace “1”s campo de redondeo<br />

or ax,0c00h ;modo “truncar”<br />

mov [nuevo],ax<br />

fldcw [nuevo] ;forza nuevo modo de redondeo<br />

fld st(0) ;duplica potencia de diez<br />

frndint ;halla parte entera del<br />

fist [exp] ;exponente y la salva<br />

fldcw [viejo] ;restaura modo de redondeo anterior<br />

fsubp st(1),st(‘0) ;halla parte fraccionaria de<br />

call falog ;potencia de diez<br />

fmulp st(1),st(0) ;multiplica por la mantisa<br />

fmul [ft1e18] ;escala mantisa par BCD<br />

frndint ;tira el remanente<br />

@@20:<br />

fcom ]fp1e17] ;¿es la mantisa < 1.0e17?<br />

fstsw [status]<br />

fwait<br />

mov ax,[status]<br />

sahf<br />

jae @@30 ;no, proceder<br />

AUTOR: PROFESOR SALVADOR SAUCEDO FLORES<br />

EDICIÓN: PROFESOR PABLO FUENTES RAMOS<br />

<strong>13</strong>-7


LENGUAJE ENSAMBLADOR 80386 <strong>PRÁCTICA</strong> <strong>13</strong><br />

fimul [int10] ;si, mantisa*10<br />

dec [exp] ;y decrementa exponente<br />

jmp @@20<br />

@@30:<br />

fcom [fp1e18] ;¿es la mantisa < 1.0e18?<br />

fstsw [status]<br />

fwait<br />

mov ax,[status]<br />

sahf<br />

jb @@40 ;si, proceder<br />

fidiv [int10] ;no, mantisa / 10<br />

inc [exp] ;e incrementa exponente<br />

jmp @@30<br />

@@40:<br />

fbstp [mant] ;salva mantisa en BCD<br />

fwait<br />

mov di,si ;direcciona cadena ASCII<br />

mov ,’+’ ;asume es positivo<br />

test [signo],200h ;verifica banderas de FXAM<br />

jz @@50 ;brinca, valor es positivo<br />

mov al,’-‘<br />

@@50:<br />

stosb ;salva símbolo + o –<br />

mov al,’0’ ;salva cero delantero<br />

stosb<br />

mov al,’.’ ;pone punto decimal<br />

stosb<br />

mov bx,8 ;apunta a últimos dígitos BCD<br />

@@60:<br />

mov al,[byte bx+mant] ;convierte byte BCD a<br />

shr al,1 ;dos dígitos ASCII<br />

shr al,1<br />

shr al,1<br />

shr al,1<br />

call digit ;convierte nibble alto<br />

mov al,[byte bx+mant]<br />

call digit ;convierte nibble bajo<br />

dec bx ;procesa valores BCD<br />

jns @@60 ;hasta convertir 18 dígitos<br />

mov al,’E’ ;pone la E para exponente<br />

stosb<br />

mov bx,[exp] ;prueba signo del exponente<br />

mov al,’+’<br />

or bx,bx<br />

jns @@70 ;brinca, exponente es positivo<br />

mov al,’-‘<br />

neg bx ;valor absoluto del exponente<br />

@@70:<br />

stosb ;salva signo del exponente<br />

AUTOR: PROFESOR SALVADOR SAUCEDO FLORES<br />

EDICIÓN: PROFESOR PABLO FUENTES RAMOS<br />

<strong>13</strong>-8


LENGUAJE ENSAMBLADOR 80386 <strong>PRÁCTICA</strong> <strong>13</strong><br />

mov ax,bx ;convierte exponente a<br />

cwd ;tres dígitos ASCII<br />

mov cx,100<br />

div cx<br />

call digit ;exponente: dígito de cientos<br />

mov ax,dx<br />

cwd<br />

mov cx,10<br />

div cx<br />

call digit ;exponente: dígito de decenas<br />

mov ax,dx<br />

call digit<br />

@@80:<br />

mov ax,di ;retorna AX = longitud de cadenas<br />

sub ax,si ;y DS:SI dirección de cadenas<br />

pop es di dx cx bx ;restaura registros<br />

ret<br />

@@100:<br />

mov di,offset CadOp ;valor de +cero<br />

mov cx,LonOp<br />

jmp @@200<br />

@@110<br />

mov di,offset CadOn ;valor de –cero<br />

mov cx,LonOn<br />

jmp<br />

@@120:<br />

mov di,offset CadVac ;valor vacío<br />

mov cx,LonVac<br />

jmp @@200<br />

@@<strong>13</strong>0:<br />

mov di,offset CadDe ;valor denormalizado<br />

mov cx,LonDe<br />

jmp @@200<br />

@@140:<br />

mov di,offset CadAn ;valor anormal<br />

mov cx,LonAn<br />

jmp @@200<br />

@@150:<br />

mov di,offset NaN ;valor NaN<br />

mov cx,LonNaN<br />

jmp @@200<br />

@@160:<br />

mov di,offset CadIP ;valor de +infinito<br />

mov cx,LonIP<br />

jmp @@200:<br />

AUTOR: PROFESOR SALVADOR SAUCEDO FLORES<br />

EDICIÓN: PROFESOR PABLO FUENTES RAMOS<br />

<strong>13</strong>-9


LENGUAJE ENSAMBLADOR 80386 <strong>PRÁCTICA</strong> <strong>13</strong><br />

@@170:<br />

mov di,offset CadIN ;valor de –infinito<br />

mov cx,LonIN<br />

@@200:<br />

xchg si,di ;SI = cadena enlatada<br />

push di, ;DI = área del llamador<br />

rep movsb ;copia cadena enlatada<br />

pop si ;restaura SI<br />

fstp st(0) ;descarta valor original<br />

jmp @@80<br />

TipoTab dw @@140 ;0000 +anormal<br />

dw @@150 ;0001 +NaN<br />

dw @@140 ;0010 –anormal<br />

dw @@150 ;0011 -NaN<br />

dw @@10 ;0100 +normal<br />

dw @@160 ;0101 +infinito<br />

dw @@10 ;0110 –normal<br />

dw @@170 ;0111 –infinito<br />

dw @@100 ;1000 +cero<br />

dw @@120 ;1001 vacío<br />

dw @@110 ;1010 –cero<br />

dw @@120 ;1011 vacío<br />

dw @@<strong>13</strong>0 ;1100 +denormal<br />

dw @@120 ;1101 vacío<br />

dw @@<strong>13</strong>0 ;1110 –denormal<br />

dw @@120 ;1111 vacío<br />

ENDP ftoa<br />

;<br />

; DIGIT: Convierte el nibble bajo en AL a un dígito ASCII y lo salva en dirección dada por ES:DI<br />

; Llamar con: AL = valor a convertir en bits 0-3<br />

; ES:DI =dirección donde poner carácter ASCII<br />

; Retorna: AL = sin cambio<br />

; ES:DI = dirección+1<br />

;<br />

PROC digit ;nibble a dígito ASCII<br />

push ax ;salva registro<br />

add al,’0’ ;convierte a carácter ASCII<br />

stosb ;salva el carácter<br />

pop ax ;restaura registro<br />

ret<br />

ENDP digit<br />

end ;fin de módulo FTOA.ASM<br />

AUTOR: PROFESOR SALVADOR SAUCEDO FLORES<br />

EDICIÓN: PROFESOR PABLO FUENTES RAMOS<br />

<strong>13</strong>-10


LENGUAJE ENSAMBLADOR 80386 <strong>PRÁCTICA</strong> <strong>13</strong><br />

3.2 Capturar el programa A387.ASM, ensamblarlo y crear el programa<br />

ejecutable<br />

%TITLE “SUMA, RESTA, MULTIPLICA Y DIVIDE NÚMERO CIENTÍFICOS”<br />

; Programa A387, tipo EXE. Suma, resta, multiplica y divide dos número reales<br />

; Ensamblarlo con: tasm /zi a387<br />

; Ligarlo con: tlink /v a387<br />

IDEAL<br />

MODEL small<br />

STACK 256<br />

P386N<br />

P387<br />

Dataseg<br />

C DB -17.35 ;número real de precisión sencilla<br />

D DB 7.153 ;ídem<br />

buff DB 17,18 dup (0) ;cadena queda en buff+2<br />

PROB DB ‘División por cero’,<strong>13</strong>,10,0<br />

ST80387 DW 0<br />

RECORD SW BSY:1,C3:1,TOP:3,C2:1,C1:1,C0:1,IT:1,X:1,P:1,U:1,O:1,Z:1,DE:1,I:1<br />

rc EQU <strong>13</strong> ;ASCII de retorno de carro<br />

nl EQU 10 ;ASCII de nueva línea<br />

ClaveFin DB 0<br />

saludo DB ‘Este programa encuentra la suma, la reta, el producto y’<br />

DB ‘el cociente’,rc,nl<br />

DB ‘de dos números de punto flotante.’<br />

DB ‘Usa el coprocesador 80387.’,rc.rc,nl<br />

DB ‘formato: [+//-][.][E/e][+/-]’,rc,nl,0<br />

RepCPU DB ‘El programa requiere por lo menos un 80386 con coprocesador’,rc,nl,0<br />

A DD 99.98999264 ;4 bytes para real sencillo<br />

B DD 17.01480361 ;ídem para destino<br />

suma DD 0 ;suma en BCD<br />

resta DD 0 ;resta en BCD<br />

multi DD 2 dup (0)<br />

ResSuma DB 26 dup (0) ;resultado de la suma<br />

ResResta DB 26 dup (0) ;resultado de la resta<br />

CadSuma DB ‘La suma es…….: ‘,0<br />

CadResta DB ‘La resta es……..; ‘,0<br />

Apr1er DB ‘Teclear primer número real…:’,0<br />

Apr2do DB ‘Teclear segundo número real…:’,0<br />

ResMulti DB 26 dup (0)<br />

CadMulti DB ‘El producto es…: ‘,0<br />

CadCociente DB ‘El cociente es….: ‘,0<br />

ResCociente DB 26 dup (0)<br />

codeseg<br />

EXTRN atof:near,ftoa:near,SacaCadena:near,SacaCadena2:near<br />

EXTRN Nuevalinea:near,cpu:near,Inicia87:near<br />

AUTOR: PROFESOR SALVADOR SAUCEDO FLORES<br />

EDICIÓN: PROFESOR PABLO FUENTES RAMOS<br />

<strong>13</strong>-11


LENGUAJE ENSAMBLADOR 80386 <strong>PRÁCTICA</strong> <strong>13</strong><br />

Entra:<br />

mov ax,@data ;inicia registro<br />

mov<br />

programa:<br />

ds,ax ;de segmento de datos<br />

mov es,ax<br />

call NuevaLinea ;salta línea<br />

call cpu ;indaga tipo de CPU<br />

cmp ax,386h ;por lo menos un 80386<br />

jae<br />

@@05:<br />

@@10<br />

mov di,offset RepCPU<br />

call SacaCadena ;avisa que saldrá<br />

mov ah,4ch ;función de DOS<br />

int 21h ;para salir<br />

@@10:<br />

mov ax,0000h<br />

call Inicia87<br />

jnz @@05<br />

mov di,offset saludo ;bienvenida e instrucciones<br />

call SacaCadena<br />

call NuevaLinea<br />

mov di,offset Apr1er ;pide primer número<br />

call SacaCadena<br />

mov ah,0ah ;pide cadena de entrada<br />

mov dx,offset buff<br />

int 21h<br />

finit ;limpia pila de 387 y lo inicia<br />

mov si,offset buff+2<br />

call atof<br />

fstp [A] ;lo salva en A<br />

call NuevaLinea ;salta a siguiente línea<br />

mov di,offset Apr2do ;pide segundo número<br />

call SacaCadena<br />

mov ah,0ah<br />

mov dx,offset buff<br />

int 21h<br />

mov si,offset buff+2<br />

call atof ;lo hace flotante<br />

call NuevaLinea<br />

fst [B] ;lo salva en B<br />

fadd [A] ;suma valor en RAM<br />

call NuevaLinea<br />

mov di,offset CadSuma ;exhibe letrero de resultado<br />

call SacaCadena ;de suma<br />

fst [D] ;salvamos resultado<br />

mov si,offset ResSuma<br />

call ftoa ;convierte a ASCII<br />

mov di,offset ResSuma<br />

mov cx,ax ;trae cantidad de caracteres<br />

call SacaCadena2<br />

AUTOR: PROFESOR SALVADOR SAUCEDO FLORES<br />

EDICIÓN: PROFESOR PABLO FUENTES RAMOS<br />

<strong>13</strong>-12


LENGUAJE ENSAMBLADOR 80386 <strong>PRÁCTICA</strong> <strong>13</strong><br />

; hace la resta…<br />

fld [A] ;trae primer número<br />

fsub [B] ;resta valor en RAM<br />

call NuevaLinea<br />

mov di,offset CadResta ;exhibe letrero de resultado<br />

call SacaCadena ;de suma<br />

fst [C] ;salvamos resta<br />

mov si,offset ResResta<br />

call ftoa ;convierte a ASCII<br />

mov di,offset ResResta<br />

mov cx,ax ;trae cantidad de caracteres<br />

call SacaCadena2<br />

; hace la multiplicación…<br />

fld [A] ;trae primer número<br />

fmul [B] ;multiplica por valor en RAM<br />

call NuevaLinea<br />

mov di,offset CadMulti ;exhibe letrero de resultado<br />

call SacaCadena ;de producto<br />

fst [C] ;salvamos producto<br />

mov si,offset ResMulti<br />

call ftoa ;convierte a ASCII<br />

mov di,offset ResMulti<br />

mov cx,ax ;trae cantidad de caracteres<br />

call SacaCadena2<br />

; hace la división…<br />

fld [A] ;trae primer número<br />

fdiv [B] ;divide por el valor en RAM<br />

call NuevaLinea<br />

mov di,offset CadCociente ;exhibe letrero de resultado<br />

call SacaCadena ;de división<br />

fstsw [ST80387] ;salvamos banderas<br />

test [ST80387],MASKZ<br />

jnz @@30<br />

mov si,offset ResCociente<br />

call ftoa ;convierte a ASCII<br />

mov di,offset ResCociente<br />

mov cx,ax ;trae cantidad de caracteres<br />

call SacaCadena2<br />

@@20:<br />

fclex ;limpia excepciones<br />

mov ax,4c00h<br />

int 21h ;fin del programa<br />

@@30:<br />

mov di,offset PROB ;saca mensaje<br />

call SacaCadena ;del problema (división por cero)<br />

jmp SHORT@@20<br />

end Entra ;fin del programa A387.ASM<br />

AUTOR: PROFESOR SALVADOR SAUCEDO FLORES<br />

EDICIÓN: PROFESOR PABLO FUENTES RAMOS<br />

<strong>13</strong>-<strong>13</strong>


LENGUAJE ENSAMBLADOR 80386 <strong>PRÁCTICA</strong> <strong>13</strong><br />

3.3 Ejecutar el programa: C>A387 (Se muestran cuatro corridas)<br />

C:\SEM386>a387<br />

Este programa encuentra la suma, la resta, el producto y el cociente de dos<br />

números de punto flotante. Usa el coprocesador 80387<br />

formato: [+//-][.][E/e][+/-]<br />

Teclear primer número real…..: -54.429<br />

Teclear segundo número real..: 86.542<br />

La suma es…….: +0.321129991455078126E+002<br />

La resta es……..: -0.14097100067<strong>13</strong>86719E+003<br />

El producto es…: -0.471039458198321518E+004<br />

El cociente es….: -0.628931628222747430E+000<br />

C:\SEM386><br />

C:\SEM386>a387<br />

Este programa encuentra la suma, la resta, el producto y el cociente de dos<br />

números de punto flotante. Usa el coprocesador 80387<br />

formato: [+//-][.][E/e][+/-]<br />

Teclear primer número real…..: 1<strong>13</strong>.097<br />

Teclear segundo número real..: -34.29<br />

La suma es…….: +0.788070001220703125E+002<br />

La resta es……..: +0.147387001037597656E+003<br />

El producto es…: -0.387809623772918712E+004<br />

El cociente es….: -0.3298250<strong>13</strong>4220826<strong>13</strong>E+001<br />

C:\SEM386><br />

C:\SEM386>a387<br />

Este programa encuentra la suma, la resta, el producto y el cociente de dos<br />

números de punto flotante. Usa el coprocesador 80387<br />

formato: [+//-][.][E/e][+/-]<br />

Teclear primer número real…..: 9.87e11<br />

Teclear segundo número real..: 14.19567e-6<br />

La suma es…….: +0.987499986944000014E+012<br />

La resta es……..: +0.987499986943999986E+012<br />

El producto es…: +0.140182237339267731E+008<br />

El cociente es….: +0.695634655804740981E+017<br />

C:\SEM386><br />

AUTOR: PROFESOR SALVADOR SAUCEDO FLORES<br />

EDICIÓN: PROFESOR PABLO FUENTES RAMOS<br />

<strong>13</strong>-14


LENGUAJE ENSAMBLADOR 80386 <strong>PRÁCTICA</strong> <strong>13</strong><br />

3.4 Este programa se puede se puede depurar con Turbo Debugger mediante el<br />

siguiente comando:<br />

C>TD A387.EXE<br />

Ejecutar paso a paso las rutinas ftoa y atof y estudiar cómo trabaja.<br />

3.5 Poner los registros en 32 bits y visualizar las variables A y B, que son<br />

reales.<br />

3.6 ¿Cuál es la representación interna de -10.0 y de 25.0?<br />

4 TAREAS<br />

C:\SEM386>a387<br />

Este programa encuentra la suma, la resta, el producto y el cociente de dos<br />

números de punto flotante. Usa el coprocesador 80387<br />

formato: [+//-][.][E/e][+/-]<br />

Teclear primer número real…..: -87.654<br />

Teclear segundo número real..: 0.0<br />

La suma es…….: -0.8765399932861<strong>13</strong>28<strong>13</strong>E+002<br />

La resta es……..: -0.8765399932861<strong>13</strong>28<strong>13</strong>E+002<br />

El producto es…: -0.0000000000000000000E+000<br />

El cociente es….: División por cero<br />

C:\SEM386><br />

4.1 Introducir al programa el procedimiento Confirma y llamarlo para verificar<br />

la opción de realizar otro cálculo<br />

4.2 Verificar los límites de operación del coprocesador numérico corriendo<br />

A387 dando valores críticos.<br />

4.3 Agregar al programa la capacidad de recibir los dos números en la línea de<br />

comandos.<br />

4.4 En el módulo A387.ASM añadir una rutina para exhibir resultados con tres<br />

decimales de precisión, justificando a la derecha el resultado y si el mismo<br />

no cabe en diez lugares, escribir puros asteriscos.<br />

4.5 Hacer que el programa A387 corra si el coprocesador no existe.<br />

AUTOR: PROFESOR SALVADOR SAUCEDO FLORES<br />

EDICIÓN: PROFESOR PABLO FUENTES RAMOS<br />

<strong>13</strong>-15

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!