NASM - The Netwide Assembler
NASM Forum => Example Code => Topic started by: avcaballero on February 10, 2012, 12:32:33 PM
-
Hello, from time to time always someone ask for any FTOA example, here it is my version.
; *************************************************************
; * Print a real number on the screen *
; * (c) Alfonso Víctor Caballero Hurtado *
; * http://www.abreojosensamblador.net/ *
; * You can use it but, credit ;), don't be a lamer *
; *************************************************************
; 1.005
; 0 01111111 00000001010001111010111b = 3F 80 A3 D7h
; 0.0005
; 0 01110100 00000110001001001101111b = 3A 03 12 6Fh
; 2^(116-127) * 1.00000110001001001101111
; 1 10000111 00110001101000000000000b = C3 98 D0 00h
; -1 * 2^(135-127) * 1.00110001101 = -100110001.101 = -305.625
[org 100h]
[section .text]
mov eax, [vdNumero]
; Recogemos el signo (1 bit: extremo izquierda)
mov byte [rbSigno], 0 ; Suponemos sin signo
shl eax, 1
jnc @Sgte1
mov byte [rbSigno], 1
@Sgte1:
; Recuperamos el exponente (8 bits siguientes)
mov ebx, eax
shr ebx, 23+1
sub ebx, 127
mov word [rwExpon], bx
xor cx, cx ; Suponemos exponente positivo
or bx, bx
jns @ExpPositivo
mov cx, bx
neg cx
mov word [rwExpon], 0
@ExpPositivo:
; Recuperamos la mantisa
shl eax, 7 ; Eliminamos el exponente
or eax, 10000000000000000000000000000000b ; Ponemos el 1.
shr eax, 9 ; Lo ponemos su sitio, ya sin exponente
call CheckExpNeg
mov ecx, 0
@Sin_Exp: ; Eliminamos los ceros a la derecha
inc ecx
mov ebx, eax
shr eax, 1
jnc @Sin_Exp
mov eax, ebx
mov dword [vdLonMantisa], 23
sub dword [vdLonMantisa], ecx
; Recogemos la parte entera
mov ebx, eax ; eax ya tiene el 1. y no tiene ceros a la derecha
mov cx, word [vdLonMantisa]
sub cx, word [rwExpon]
and ecx, 0FFFFh ; Eliminamos la parte de arriba, por si acaso
mov dword [vdLonDecimal], ecx
shr ebx, cl ; Eliminamos decimales, sólo queda parte entera
mov word [rwEntera], bx ; Parte entera
; Recogemos la parte decimal
mov ebx, eax ; eax ya tiene el 1. y no tiene ceros a la derecha
mov cx, 32 ; 16
sub cx, word [vdLonDecimal]
shl ebx, cl ; Eliminamos la parte entera
shr ebx, cl ; Ponemos parte decimal contra borde derecho
; ** Aquí ya hemos desmenuzado el número real,
; ** ahora hay que convertirlo a ascii
; Parte decimal
call InitSum
mov ecx, dword [vdLonDecimal] ; Contador de posiciones
@B_Decimal:
shr ebx, 1
jnc @B_Sgte1
call Divide ; Resultado en vmBufDivision
call Suma ; Resultado en vdSumaFinal
@B_Sgte1:
dec ecx
jnz @B_Decimal
call Sum2ASCII ; Convierte la suma en ASCII
call CopiaSumaMatFinal ; Copiamos la suma en la matriz final
; Separador
mov byte [di], '.'
dec di
; Parte entera
mov ax, [rwEntera]
call Bin2ASCII
; Signo
cmp byte [rbSigno], 1
jnz @Fin
mov byte [di], '-'
@Fin:
; Imprimimos el número
mov ah, 9
mov dx, di
int 21h
; Salimos al DOS
ret
CheckExpNeg:
; Propósito: Chequeamos si el exponente fuera negativo para acomodar mantisa
; Entrada : eax: Número, cx: Exponente (0 si positivo, otro caso negativo)
; eax ya tiene el 1 a la izquierda y sin exponente
; Salida : eax
; Destruye : eax
or cx, cx
jz @cen_Fin
shr eax, cl
@cen_Fin:
ret
BaseDecimal:
; Propósito: devuelve la base para los decimales
; Entrada : eax
; Salida : edx: la base
; Destruye : Ninguna
push eax
push ebx
push esi
mov ebx, 10
@b_bucle:
mul ebx
dec esi
jnz @b_bucle
mov edx, eax
pop esi
pop ebx
pop eax
ret
Bin2ASCII:
; Propósito: convierte binario a ascii y lo va metiendo en di
; Entrada : eax: num a convertir, di: donde empieza a meter en el búfer
; Salida : di donde ha terminado de meter en el búfer
; Destruye : eax, edi
push ebx
push edx
mov ebx, 10
@Bucle1:
cmp eax, 0
jz @Salir
xor edx, edx
div ebx
or dl, 30h
mov [di], dl
dec di
jmp @Bucle1
@Salir:
pop edx
pop ebx
ret
Sum2ASCII:
; Propósito: Inicializa con ceros el búfer de la suma (8 bytes)
; Entrada : Ninguna
; Salida : Ninguna
; Destruye : eax
or dword [vdSumaFinal], 30303030h
or dword [vdSumaFinal+4], 30303030h
ret
CopiaSumaMatFinal:
; Propósito: Copia el búfer de la suma en rbNumASCII
; Entrada : Ninguna
; Salida : edi
; Destruye : esi, edi
std ; Decrementamos
mov esi, vdSumaFinal + 7
mov edi, rbNumASCII + 19
mov ecx, 7
rep movsb
ret
InitSum:
; Propósito: Inicializa con ceros el búfer de la suma (8 bytes)
; Entrada : Ninguna
; Salida : Ninguna
; Destruye : eax
push ecx
push edi
mov eax, 0
mov ecx, 2
mov edi, vdSumaFinal
rep stosd
pop edi
pop ecx
ret
Suma:
; Propósito: Suma en bytes vmBufDivision con vdSumaFinal y lo deja aquí
; Entrada : Ninguna
; Salida : vdSumaFinal
; Destruye : eax
push ebx
push ecx
push edx
push esi
push edi
mov esi, vmBufDivision+7
mov edi, vdSumaFinal+7
mov ecx, 8
mov dl, 0
.Bucle:
mov al, byte [esi]
mov ah, byte [edi]
add al, ah
add al, dl
mov dl, 0
cmp al, 10
jb .Next
mov dl, 1
sub al, 10
.Next:
mov byte [edi], al
dec edi
dec esi
loop .Bucle
pop edi
pop esi
pop edx
pop ecx
pop ebx
ret
Divide:
; Propósito: Divide 10000000 por 2^cl y lo trocea en bytes
; Entrada : ecx: exponente de 2
; Salida : vmBufDivision
; Destruye : eax
push ebx
push ecx
push edx
push edi
; Limpiamos el búfer
push ecx
mov edi, vmBufDivision
mov eax, 0
mov ecx, 8/4
rep stosd
pop ecx
;
mov eax, 10000000 ; Esto es lo que dividiremos
; mov ecx, 3 ; Parámetro que indicará por cuánto dividimos
shr eax, cl ; Hademos la división por 2^cl
; Ahora troceamos la división en bytes
mov edi, vmBufDivision+7 ; Dirección donde empezamos a escribir
mov ebx, 10 ; Establecemos el divisor
.Bucle:
cmp eax, 0 ; ¿Hemos terminado?
jz .Fin
xor edx, edx ; Limpiamos de nuevo la parte superior
div ebx ; Divisimos -> cociente en edx
mov byte [edi], dl ; Guardamos el byte
dec edi ; Actualizamos puntero
jmp .Bucle
.Fin:
pop edi
pop edx
pop ecx
pop ebx
ret
[section .data]
; vdNumero dd 305.625
vdNumero dd 0.0005
vdAcumDec dd 0
rbNumASCII: times 20 db ' '
db "$"
[section .bss]
vdSumaFinal resb 8
vmBufDivision resb 8
vdLonMantisa resd 1
vdLonDecimal resd 1
rwEntera resw 1
rdDecimal resw 1
rwExpon resw 1
rbSigno resb 1
-
Nice! I've got a half-baked "ftoa" (and an "atof") that I've used (to file federal employment taxes, even!), but I think I like yours better. Mine depends on "fbstp" and "fbld", yours is pure bit-bashing.
I think I see something that might become a problem... if we were to go on and try to convert a second number, for example...
CopiaSumaMatFinal:
; Propósito: Copia el búfer de la suma en rbNumASCII
; Entrada : Ninguna
; Salida : edi
; Destruye : esi, edi
std ; Decrementamos
mov esi, vdSumaFinal + 7
mov edi, rbNumASCII + 19
mov ecx, 7
rep movsb
ret
You set the direction flag "down"... and leave it there. I think it might be an "improvement" to add a "cld" after the "rep movsb", just before the "ret". What do you think?
I'll see if I can dig up an example of mine to post, just for comparison, but I think I like this better.
Best,
Frank
-
Here we go... This might be useful to discuss "How cold IS it?". After an early snowstorm at the end of October, it's been pretty mild here this winter. I understand it's been "cold as blazes" in Europe!
;-----------------------------------------------
; converts centigrade to fahrenheit, & visa versa
;
; nasm -f bin -o myfile.com myfile.asm
;--------------------------------------
org 100h
BUFSIZ equ 8
section .data
prompt0 db 13, 10, 7, 'Pay Attention!!!', 13, 10, '$'
prompt1 db 13, 10, 'This humble program will convert', 13, 10
db 'degrees centigrade to degrees Fahrenheit,', 13, 10
db 'or Fahrenheit to centigrade (Celsius).', 13, 10
db 'Please enter "C" or "F" to indicate the', 13, 10
db 'temperature units in which you will INPUT', 13, 10
db 'the value to be converted.', 13, 10, 10 , '$'
promptc db 'Please enter degrees C to convert to F:', 13, 10, '$'
promptf db 'Please enter degrees F to convert to C:', 13, 10, '$'
that db 13, 10, "That's $"
degrees db ' degrees $'
bye db 13, 10, 10, "Thanks for playing!", 13, 10, '$'
word_10 dw 10 ; multiplier for the float-to-ascii routine
; for C->F, F->C routines
float_32 dq 32.0
float_5 dq 5.0
float_9 dq 9.0
section .bss
buffer resb BUFSIZ + 2 ; buffer for our input string
result_units resb 1 ; holds 'C' or 'F'
numbuf resb 20h ; buffer for ftoa
bcdbuf rest 1 ; 10 byte scratch area for ftoa
;--------------------
section .text
; cheap-a** cls - reset text mode
mov ax, 3
int 10h
instruct:
; tell 'em what we're gonna do, and ask for input
mov dx, prompt1
mov ah, 9
int 21h
; get input - one key, no echo
mov ah, 8
int 21h
; force uppercase
and al, 0DFh
; did they get it right?
cmp al, 'C'
je do_c2f
cmp al, 'F'
je do_f2c
; smack their a**, and make 'em do it over
mov dx, prompt0
mov ah, 9
int 21h
jmp short instruct
; store the letter we'll display at the end
; we also use it as a "flag" to decide f->c or c->f
; and set up appropriate prompt
do_c2f:
mov byte [result_units], 'F'
mov dx, promptc
jmp short both
do_f2c:
mov byte [result_units], 'C'
mov dx, promptf
both:
; display the prompt, "C" or "F", asking for input
mov ah, 9
int 21h
; get string input, set "max size" first
mov byte [buffer], BUFSIZ
mov ax, 0C0Ah
mov dx, buffer
int 21h
; since atof expects a zero-terminated string, do so.
mov bl, [buffer + 1]
xor bh, bh
mov byte [buffer + 2 + bx], 0
; convert the string to a float in st(0)
; remember that input text starts at 2 bytes into the buffer
mov si, buffer + 2
call atof
jnc good_num
; if they gave us trash, give 'em trash back
; and make 'em do it over
mov dx, prompt0
int 21h
mov dx, promptc
cmp byte [result_units], 'F'
je both
mov dx, promptf
jmp short both
good_num:
; okay, they did right, do the calculation they want
cmp byte [result_units], 'C'
jne calc_c2f
fsub qword [float_32]
fmul qword [float_5]
fdiv qword [float_9]
jmp short display
calc_c2f:
fmul qword [float_9]
fdiv qword [float_5]
fadd qword [float_32]
; Whew! That was tough!
display:
; convert st(0) to ascii string at di - cx decimal places
mov cx, 2
mov di, numbuf
call ftoa
; ftoa returns a zero-terminated string,
; fix it for int 21h/9 - '$'-terminate
dec di
reterminate:
cmp byte [di + 1], 1
inc di
jnc reterminate
mov byte [di], '$'
; tell 'em what we're going to do
mov ah, 9
mov dx, that
int 21h
; tell 'em the number
mov dx, numbuf
int 21h
; and the units
mov dx, degrees
int 21h
mov ah, 2
mov dl, [result_units]
int 21h
; say Buhbye - enhancement - go again?
mov ah, 9
mov dx, bye
int 21h
exit:
mov ah,4Ch
int 21h
;------------------------------------------------
; atof - converts ascii string to float
; expects: si pointed to zero-terminated string
; returns: float in st(0)
; carry set if invalid digit encountered
;-------------------------------------------------
atof:
push ax
push bx
push cx
push dx
push di
push si
xor bx, bx
xor cx, cx
dec cx ; set cx FFFF - no point found
xor dx, dx
mov byte [bcdbuf + 9], 0 ; assume positive
mov di, si ; save our "beginning of buffer"
.af0:
mov al, [si]
inc si
cmp al, '-'
jnz .notneg
mov byte [bcdbuf + 9], 80h
jmp short .af0
.notneg:
cmp al, '.'
jnz .notpt
inc cx
jmp short .af0
.notpt:
cmp al, ' '
jz .af0
cmp cx, 0FFFFh
jz .af05
inc cx
.af05
or al, al ; end of string?
jnz .af0
dec si
dec si
cmp cx, 0FFFFh
jnz .af07
xor cx, cx
jmp short .af1
.af07
dec cx
.af1:
cmp si, di
jc .done
mov al, [si]
dec si
cmp al, ' '
jz .af1
cmp al, '-'
jz .af1
cmp al, '.'
jz .af1
cmp al, 3Ah
jnc .invalid
cmp al, 30h
jc .invalid
and al, 0Fh
or dh, dh
jnz .notfirst
or dl, al
inc dh
jmp short .af1
.notfirst:
shl al, 4
or dl, al
mov [bcdbuf + bx], dl
xor dx, dx
inc bx
jmp .af1
.invalid
stc
jmp short .done3
.done
or dh, dh
jz .padbcd
and dl, 0Fh
mov [bcdbuf + bx], dl
inc bx
.padbcd
cmp bx, byte 9
jz .done2
mov byte [bcdbuf + bx], 0
inc bx
jmp short .padbcd
.done2
fbld [bcdbuf]
or cx, cx
jz .done25
.tendiv:
fidiv word [word_10]
loop .tendiv
.done25
clc
.done3:
pop si
pop di
pop dx
pop cx
pop bx
pop ax
ret
;--------------------------------------------
;-----------------------------------------------------
; ftoa - converts floating point to string
;
; Based on some code "sponged" from a post to clax
; From: "Jim Morrison" <astrolabe at ntplx dot net>
;
; Expects: Number to convert is on stack top - st(0)
; di points to buffer to store string
; cx = Decimal Places.
;-------------------------------------------------------------
ftoa:
push ax
push cx
push dx
push di
push si
mov dx, cx ; save a copy of dec places
; if no decimal (integer)
jcxz .f2a2 ; skip multiply by ten loop
.f2a1: ; else loop to "scale" number
fimul word [word_10]
loop .f2a1
.f2a2:
fbstp [bcdbuf] ; convert to bcd and store
mov si, bcdbuf ; we'll pull digits from there
mov cx, 9
.f2a3:
lodsb ; get a pair of digits
mov ah, al ; move a copy to ah
shr ah, 4 ; shift out low nibble, keeping high
and ax, 0F0Fh ; mask out the digits we want
add ax, 3030h ; convert 'em both to ascii
push ax
mov al, ah ; swap and store the other digit
push ax
loop .f2a3 ; until done
cmp byte [bcdbuf+9], 0 ; sign flag at bcdbuf + 9 ?
je .f2a6
mov al, '-' ; minus sign if we need it
stosb ; store it at front of our string
.f2a6:
mov cx, 18
xor dh, dh
inc dl
.poploop
pop ax
cmp al, '0'
jnz .store
or dh, dh
jnz .store
jmp short .nostore
.store
stosb
inc dh
.nostore
cmp cl, dl
jne .nopoint
or dh, dh ; if we haven't encountered a non-zero
jnz .nolz
mov al, '0' ; put a zero before the decimal point
stosb
.nolz
mov al, '.' ; decimal point
stosb ; and store it
inc dh
.nopoint
loop .poploop
mov al, 0
stosb
pop si
pop di
pop dx
pop cx
pop ax
ret
;--------------------------------------------------
These routines don't check for overflow, underflow, denormals, NANs, etc. They are known to return garbage if the number exceeds certain limits. I try to avoid this in this example by limiting the number of characters that can be entered. :)
I have a "Linux version", too, which I could post if anyone's interested. Note that this one works on "double precision" floats (qwords not dwords). Although it's been "tested", no guarantee that it gives a correct answer!
Best,
Frank
-
Hello, Frank, sorry for answer late, but I'm ussually offline on weekends... I did it as an example, so, it is posible that it need some modifications in order to work well as an subroutine, plz let me take it a look
-
Yes, you were right, as usual, but I think is better use cld/std before it is needed, also pushf/popf to avoid problems...
Comments in spanish, sorry.
; *************************************************************
; * Print a real number on the screen *
; * (c) Alfonso Víctor Caballero Hurtado *
; * http://www.abreojosensamblador.net/ *
; * You can use it but, credit ;), don't be a lamer *
; *************************************************************
; 1.005
; 0 01111111 00000001010001111010111b = 3F 80 A3 D7h
; 0.0005
; 0 01110100 00000110001001001101111b = 3A 03 12 6Fh
; 2^(116-127) * 1.00000110001001001101111
; 1 10000111 00110001101000000000000b = C3 98 D0 00h
; -1 * 2^(135-127) * 1.00110001101 = -100110001.101 = -305.625
cbFinChar EQU "$"
cbNFloats EQU 5
%MACRO PrintFloat 1
mov ah, 9
mov dx, %1
int 21h
%ENDMACRO
[org 100h]
[section .text]
mov ecx, cbNFloats
mov esi, vdNumero
@Bucle:
call FTOA
PrintFloat di
add esi, 4
loop @Bucle
; Salimos al DOS
ret
FTOA:
; Propósito: Convierte float number en ASCII
; Entrada : esi: número en coma flotante
; Salida : di: dirección donde empezar a imprimir
; Destruye : Ninguna
push ebx
push ecx
push edx
push esi
mov eax, [esi]
; Recogemos el signo (1 bit: extremo izquierda)
mov byte [rbSigno], 0 ; Suponemos sin signo
shl eax, 1
jnc .Sgte1
mov byte [rbSigno], 1
.Sgte1:
; Recuperamos el exponente (8 bits siguientes)
mov ebx, eax
shr ebx, 23+1
sub ebx, 127
mov word [rwExpon], bx
xor cx, cx ; Suponemos exponente positivo
or bx, bx
jns .ExpPositivo
mov cx, bx
neg cx
mov word [rwExpon], 0
.ExpPositivo:
; Recuperamos la mantisa
shl eax, 7 ; Eliminamos el exponente
or eax, 10000000000000000000000000000000b ; Ponemos el 1.
shr eax, 9 ; Lo ponemos su sitio, ya sin exponente
call CheckExpNeg
mov ecx, 0
.Sin_Exp: ; Eliminamos los ceros a la derecha
inc ecx
mov ebx, eax
shr eax, 1
jnc .Sin_Exp
mov eax, ebx
mov dword [vdLonMantisa], 23
sub dword [vdLonMantisa], ecx
; Recogemos la parte entera
mov ebx, eax ; eax ya tiene el 1. y no tiene ceros a la derecha
mov cx, word [vdLonMantisa]
sub cx, word [rwExpon]
and ecx, 0FFFFh ; Eliminamos la parte de arriba, por si acaso
mov dword [vdLonDecimal], ecx
shr ebx, cl ; Eliminamos decimales, sólo queda parte entera
mov word [rwEntera], bx ; Parte entera
; Recogemos la parte decimal
mov ebx, eax ; eax ya tiene el 1. y no tiene ceros a la derecha
mov cx, 32 ; 16
sub cx, word [vdLonDecimal]
shl ebx, cl ; Eliminamos la parte entera
shr ebx, cl ; Ponemos parte decimal contra borde derecho
; ** Aquí ya hemos desmenuzado el número real,
; ** ahora hay que convertirlo a ascii
; Parte decimal
call InitSum
mov ecx, dword [vdLonDecimal] ; Contador de posiciones
.B_Decimal:
shr ebx, 1
jnc .B_Sgte1
call Divide ; Resultado en vmBufDivision
call Suma ; Resultado en vdSumaFinal
.B_Sgte1:
dec ecx
jnz .B_Decimal
call Sum2ASCII ; Convierte la suma en ASCII
call CopiaSumaMatFinal ; Copiamos la suma en la matriz final
; Separador
mov byte [di], '.'
dec di
; Parte entera
mov ax, [rwEntera]
call Bin2ASCII
; Signo
cmp byte [rbSigno], 1
jnz .Fin
mov byte [di], '-'
.Fin:
pop esi
pop edx
pop ecx
pop ebx
ret
CheckExpNeg:
; Propósito: Chequeamos si el exponente fuera negativo para acomodar mantisa
; Entrada : eax: Número, cx: Exponente (0 si positivo, otro caso negativo)
; eax ya tiene el 1 a la izquierda y sin exponente
; Salida : eax
; Destruye : eax
or cx, cx
jz .cen_Fin
shr eax, cl
.cen_Fin:
ret
BaseDecimal:
; Propósito: devuelve la base para los decimales
; Entrada : eax
; Salida : edx: la base
; Destruye : Ninguna
push eax
push ebx
push esi
mov ebx, 10
.b_bucle:
mul ebx
dec esi
jnz .b_bucle
mov edx, eax
pop esi
pop ebx
pop eax
ret
Bin2ASCII:
; Propósito: convierte binario a ascii y lo va metiendo en di
; Entrada : eax: num a convertir, di: donde empieza a meter en el búfer
; Salida : di donde ha terminado de meter en el búfer
; Destruye : eax, edi
push ebx
push edx
mov ebx, 10
.Bucle1:
cmp eax, 0
jz .Salir
xor edx, edx
div ebx
or dl, 30h
mov [di], dl
dec di
jmp .Bucle1
.Salir:
pop edx
pop ebx
ret
Sum2ASCII:
; Propósito: Inicializa con ceros el búfer de la suma (8 bytes)
; Entrada : Ninguna
; Salida : Ninguna
; Destruye : eax
or dword [vdSumaFinal], 30303030h
or dword [vdSumaFinal+4], 30303030h
ret
CopiaSumaMatFinal:
; Propósito: Copia el búfer de la suma en rbNumASCII
; Entrada : Ninguna
; Salida : edi
; Destruye : esi, edi
pushf
mov esi, vdSumaFinal + 7
mov edi, rbNumASCII + 19
mov ecx, 7
std ; Decrementamos
rep movsb
popf
ret
InitSum:
; Propósito: Inicializa con ceros el búfer de la suma (8 bytes)
; Entrada : Ninguna
; Salida : Ninguna
; Destruye : eax
pushf
push ecx
push edi
mov eax, 0
mov ecx, 2
mov edi, vdSumaFinal
cld
rep stosd
pop edi
pop ecx
popf
ret
Suma:
; Propósito: Suma en bytes vmBufDivision con vdSumaFinal y lo deja aquí
; Entrada : Ninguna
; Salida : vdSumaFinal
; Destruye : eax
push ebx
push ecx
push edx
push esi
push edi
mov esi, vmBufDivision+7
mov edi, vdSumaFinal+7
mov ecx, 8
mov dl, 0
.Bucle:
mov al, byte [esi]
mov ah, byte [edi]
add al, ah
add al, dl
mov dl, 0
cmp al, 10
jb .Next
mov dl, 1
sub al, 10
.Next:
mov byte [edi], al
dec edi
dec esi
loop .Bucle
pop edi
pop esi
pop edx
pop ecx
pop ebx
ret
Divide:
; Propósito: Divide 10000000 por 2^cl y lo trocea en bytes
; Entrada : ecx: exponente de 2
; Salida : vmBufDivision
; Destruye : eax
pushf
push ebx
push ecx
push edx
push edi
; Limpiamos el búfer
push ecx
mov edi, vmBufDivision
mov eax, 0
mov ecx, 8/4
cld
rep stosd
pop ecx
;
mov eax, 10000000 ; Esto es lo que dividiremos
; mov ecx, 3 ; Parámetro que indicará por cuánto dividimos
shr eax, cl ; Hademos la división por 2^cl
; Ahora troceamos la división en bytes
mov edi, vmBufDivision+7 ; Dirección donde empezamos a escribir
mov ebx, 10 ; Establecemos el divisor
.Bucle:
cmp eax, 0 ; ¿Hemos terminado?
jz .Fin
xor edx, edx ; Limpiamos de nuevo la parte superior
div ebx ; Divisimos -> cociente en edx
mov byte [edi], dl ; Guardamos el byte
dec edi ; Actualizamos puntero
jmp .Bucle
.Fin:
pop edi
pop edx
pop ecx
pop ebx
popf
ret
[section .data]
; vdNumero dd 305.625
vdNumero dd 0.0005
dd 1.0015
dd 100.0275
dd 230.0175
dd -35.0178
vdAcumDec dd 0
rbNumASCII: times 20 db ' '
db 13, 10, cbFinChar
[section .bss]
vdSumaFinal resb 8
vmBufDivision resb 8
vdLonMantisa resd 1
vdLonDecimal resd 1
rwEntera resw 1
rdDecimal resw 1
rwExpon resw 1
rbSigno resb 1
; >realcn01
; .0004998
; 1.0014996
; 100.0274962
; 230.0174863
; -35.0177992