I have a work to do in Assembly. With the value of a radius given by the user, It only calculates the area of a circle. It has to work in 8086 and
not in 80386. I think that the problem is that the value is loaded to the FPU stack as a string. How do I convert a string to a floating point value?
I'm using
MASM 6.14 and I really can't use another compiler.
Can someone please please help me?

.8087
;include include\stdlib.a
; includelib lib\stdlib.lib
.MODEL SMALL
.STACK 200h
; this macro prints a string that is given as a parameter, example:
; PRINTN 'hello world!'
; the same as PRINT, but new line is automatically added.
PRINTN MACRO sdat
LOCAL next_char, s_dcl, printed, skip_dcl
PUSH AX ; store registers...
PUSH SI ;
JMP skip_dcl ; skip declaration.
s_dcl DB sdat, 0Dh,0Ah, 0
skip_dcl:
LEA SI, s_dcl

next_char:
MOV AL, CS:[SI]
CMP AL, 0
JZ printed
INC SI
MOV AH, 0Eh ; teletype function.
INT 10h
JMP next_char
printed:
POP SI ; re-store registers...
POP AX ;
ENDM
data Segment
menu db ' ',0ah,0dh
db ' 2006/2007 ',0ah,0dh
db ' ',0ah,0dh
db ' þþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþ ',0ah,0dh
db ' þ Computer Architecture þ ',0ah,0dh
db ' þþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþ ',0ah,0dh
db ' þ 1Calculate Area þ ',0ah,0dh
db ' þ 2HELP þ ',0ah,0dh
db ' þ 3EXIT þ ',0ah,0dh
db ' þþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþ ',0ah,0dh
db ' ',0ah,0dh
db ' ',0ah,0dh
db ' ',0ah,0dh
db ' ',0ah,0dh
db ' ',0ah,0dh
db ' ',0ah,0dh
db ' ',0ah,0dh
db ' ',0ah,0dh
db ' ',0ah,0dh
db 'Choose an option:','$'

mens1 Db 0ah,0ah,0dh,'Introduce the radius:','$'
mens2 Db 0ah,0ah,0dh,'Introduce the second number:','$'
mens3 Db 0ah,0ah,0dh,'The area of the circle is:','$'
menserro db 0ah,0ah,0dh,' (ERROR) Introduce a number between 1 and 5',0ah,0dh,'$'
prima db 0ah,0dh,' Press ENTER and then introduce a number',0ah,0dh,'$'
menserro2 db 0ah,0dh,' (ERROR) Introduce a letter (Y)es or (N)o',0ah,0dh,'$'
prima2 db 0ah,0dh,' Press ENTER and then introduce a letter',0ah,0dh,'$'
nota db 0dh,' NOTe:(Introduce the letters in uppercase)',0ah,0dh,'$'
real Db 0ah,0dh,'Work done by *** and ***',0dh,'$'
sair db 0ah,0ah,0dh,'Quit? Y/N',0ah,0dh,'$'
result db 100 dup (?)
db '$'
num dw 0
valx DW ?
num2 dw 0
posinum dw 32, 16, 32 dup (?)
posinum2 dw 32, 16, 32 dup (?)
convert dw 0001h, 000ah, 0064h, 03E8h, 2710h
convertaf dw $
numreal real4 1.0
resreal real4 ?
temp REAL4 ?
Resul dd ? ; Variable para el result
Desca dd ? ; Variable para correccion de pila
data Ends
Pilha Segment 'stack'
db 100 dup(?)
pilha ends
Code Segment
Assume CS: Code, DS: data, es:SEG temp
call clescr
call soma
call ajuda
call exit
call erro
call erro2
Inicio: ;beginning of program

mov ax,data ;move data para ax
mov ds,ax ;move ax para ds
mov es,ax ;move ax para es
jmp soma
clescr proc near
mov ah,6
xor cx,cx
mov dx,184fh
mov al,0
mov bh,7
int 10h
clescr endp
mov dx,dx
or dx,dx

mov ah,01h
mov cx,07h
int 10h

lea dx,menu
mov ah,09h
int 21h
mov ah, 1
int 21h
mov cl,al

cmp cl,'1'
jz soma

cmp cl,'2'
jz Ajuda

cmp cl,'3'
jz exit
jnz erro
jmp soma

erro proc near
lea dx,menserro
mov ah,09h
int 21h
lea dx,prima
mov ah,09h
int 21h
mov ah,1
int 21h
jmp inicio
erro endp

Ajuda proc near
Ajuda endp

soma proc near
lea dx,mens1
mov ah,09h
int 21h

mov ah,0ah
lea dx,posinum
int 21h

call convertnum
mov num,bx

xor dx,dx
mov ax,num
mul ax
jnc somaconv
adc dx,0
somaconv:
; call converteascii
; lea dx,mens3
;mov ah,09h
;int 21
;lea dx,result
;mov ah,09h
;int 21h
; lea dx,real
; mov ah,09h
; int 21h


;numreal real4 5.0
;resreal real4 ?
;temp REAL4 ?

finit
fld1;numreal
fmul st,st(0) ;x*x
fldpi
fmul
;fstp resreal
fstp Dword Ptr ds:[Resul]
;fstp Dword Ptr ds:[Desca]
fwait


;mov result,dword ptr resreal
mov bx,ds
call convertenum
mov num,bx

xor dx,dx
mov ax,num

;mov ax,resreal

call converteascii
lea dx,mens3
mov ah,09h
int 21h
lea dx,result
mov ah,09h
int 21h


;Fim area
jmp exit
soma enDP

convertenum proc near
mov dx,0ah
cmp num,0
jnz convertenum1
lea di,posinum + 1
mov cx,[di]
lea si,posinum + 2
jmp convertenum2
convertenum1:

lea di,posinum2 + 1
mov cx,[di]
lea si,posinum2 + 2

convertenum2:

xor ch,ch
lea di,convert
dec si
add si,cx


xor bx,bx
std
convertenum3:
lodsb
cmp al,'0'
jb convertenum4
cmp al,'9'
ja convertenum4
sub al,30h
cbw
mov dx,[di]
mul dx
jc convertenum5
add bx,ax

jc convertenum5
add di,2
loop convertenum3
jmp convertenum6
convertenum4:
jmp convertenum6
convertenum5:
mov num,2
convertenum6:
cld
ret
convertenum endp
converteascii proc near

push dx
push ax
lea si,result
mov cx,10


converteascii1:


pop ax
pop dx
mov bx,ax
mov ax,dx
lea si,result
add si,11
mov cx,10
introdnum:
dec si
xor dx,dx
div cx
mov di,ax
mov ax,bx
div cx
mov bx,ax
mov ax,di
add dl,30h
mov [si],dl
or ax,ax
jnz introdnum
or bx,bx
jnz introdnum
ret
converteascii endp
exit proc near
lea dx,sair
mov ah,09h
int 21h

mov ah,1
int 21h

mov cl,al
cmp cl,'N'
jz inicio
cmp cl,'S'
jz fim

cmp cl,'n'
jz inicio
cmp cl,'s'
jz fim

jnz erro2
exit endp
erro2 proc near
lea dx,menserro2
mov ah,09h
int 21h
lea dx,prima2
mov ah,09h
int 21h
lea dx,nota
mov ah,09h
int 21h
mov ah,1
int 21h
jmp exit
erro2 endp
; process overlow error:
;++++++++++++++++++++++ Getchar +++++++++++++++++++++++++++++++++++++++++++++
getch proc near
xor ax,ax
mov ah,08h
int 21h
ret
getch endp

Fim:

mov ah,4ch
int 21h
Code Ends
End Inicio

Whatever that big blog of stuff is, it isn't going to make printable floating point values. I didn't see anything in there doing BCD which almost any reasonable number display routine will have to do.

Whatever that big blog of stuff is, it isn't going to make printable floating point values. I didn't see anything in there doing BCD which almost any reasonable number display routine will have to do.

Do you mean tha I have to convert from bcd to real and from real to bcd?

Do you mean tha I have to convert from bcd to real and from real to bcd?

Every floating point printing routine I've ever worked with for x86 scales the exponent and uses the NPX(or emulator) BCD to convert the 64 bit fraction for printing.

I think you need to take a look at the IEEE 754 numeric standard. Then all of this will make a lot more sense. The Intel programmer ref for 486 includes the NPX supplement, its a seperate doc for 387. The 286 programmers ref has the 287 supplement included, and the 8086 docs did it as a seperate doc.


If you want to do this without hardware BCD(or x87 emulator) you've got a challenge.

Every floating point printing routine I've ever worked with for x86 scales the exponent and uses the NPX(or emulator) BCD to convert the 64 bit fraction for printing.

I think you need to take a look at the IEEE 754 numeric standard. Then all of this will make a lot more sense. The Intel programmer ref for 486 includes the NPX supplement, its a seperate doc for 387. The 286 programmers ref has the 287 supplement included, and the 8086 docs did it as a seperate doc.


If you want to do this without hardware BCD(or x87 emulator) you've got a challenge.

Does anyone know if there is a way to disassemble a c file into an Assembly file? If I could do that, I'd do this program in c and then try to understand it in assembly.

I have reformulated my work but now I just can´t get the result in floating point. Does anyone know why?

.MODEL SMALL
.386
.387
.STACK 200h ; reserva 1k para a stack

data Segment
menu db ' ',0ah,0dh
db ' 2006/2007 ',0ah,0dh
db ' ',0ah,0dh
db ' þþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþ ',0ah,0dh
db ' þ Arquitectura Computadores I þ ',0ah,0dh
db ' þþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþ ',0ah,0dh
db ' þ 1 - Calculate Area þ ',0ah,0dh
db ' þ 2 - Help þ ',0ah,0dh
db ' þ 3 - EXIT þ ',0ah,0dh
db ' þþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþ ',0ah,0dh
db ' ',0ah,0dh
db ' ',0ah,0dh
db ' ',0ah,0dh
db ' ',0ah,0dh
db ' ',0ah,0dh
db ' ',0ah,0dh
db ' ',0ah,0dh
db ' ',0ah,0dh
db ' ',0ah,0dh
db 'Choose an option:','$'
menuajuda db ' ',0ah,0dh
db ' 2006/2007 ',0ah,0dh
db ' ',0ah,0dh
db ' þþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþ ',0ah,0dh
db ' þ Area of Circle þ ',0ah,0dh
db ' þþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþ ',0ah,0dh
db ' This program calculates the area of a þ ',0ah,0dh
db ' þ circle given the radius by the user þ ',0ah,0dh
db ' þ þ ',0ah,0dh
db ' þþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþ ',0ah,0dh
db ' þ þ ',0ah,0dh
db ' þ þ ',0ah,0dh
db ' þþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþ ',0ah,0dh
db ' ',0ah,0dh
db ' ',0ah,0dh
db ' ',0ah,0dh
db ' ',0ah,0dh
db ' ',0ah,0dh
db ' ',0ah,0dh
db 'Return to the menu.','$'
ILLEGAL DB 0DH,0AH,'Introduce the value: $'
mens1 Db 0ah,0ah,0dh,'Radius: ','$'
mens3 Db 0ah,0ah,0dh,'The area of the circle is:','$'
menserro1 Db 0ah,0ah,0dh,'Introduce numbers only','$'
menserro db 0ah,0ah,0dh,' (ERROR) Introduce a number between 1 and 3',0ah,0dh,'$'
prima db 0ah,0dh,' Press ENTER and a number ','$'
menserro2 db 0ah,0dh,' (ERROR) Introduce (Y)es or (N)o','$'
prima2 db 0ah,0dh,' Press ENTER and then a letter','$'
sair db 0ah,0ah,0dh,'Quit? Y/N ','$'
resultado db 100 dup (?)
db '$'
temp real4 ?
; x dw ?
x real4 ?

data Ends
Pilha Segment 'stack'
db 100 dup(?)
pilha ends
Code Segment
Assume CS: Code, DS: data, es:nothing
call MenuPrincipal
;----------------------------------------------
Inicio:

mov ax,data ;move data para ax
mov ds,ax ;move ax para ds
mov es,ax ;move ax para es
;++++++++++++Limpa o ecran+++++++++++++++
clescr proc near
call clrscr1
mov ah,6
mov bh,9Fh
xor cx,cx
mov dh, 24
mov dl, 79
mov al,cl
int 10h
ret
clescr endp
clrscr1 proc near
mov ah,6
mov ah,00h
mov al,03h
int 10h
ret
clrscr1 endp
MenuPrincipal proc near
call clescr
mov dx,dx
or dx,dx

mov ah,01h
mov cx,07h
int 10h

lea dx,menu
mov ah,09h
int 21h
call getch
mov cl,al
cmp cl,'1'
jz calculo
cmp cl,'2'
jz Ajuda

cmp cl,'3'
jz exit
jnz erro
jmp calculo
MenuPrincipal endp
erroNumero proc near

lea dx,menserro1
mov ah,09h
int 21h
lea dx,prima
mov ah,09h
int 21h
call getch
jmp MenuPrincipal
erroNumero endp

erro proc near

lea dx,menserro
mov ah,09h
int 21h
lea dx,prima
mov ah,09h
int 21h
call getch
jmp MenuPrincipal
erro endp

Ajuda proc near
call clescr
lea dx,menuajuda
mov ah,09h
int 21h
call getch
jmp MenuPrincipal
Ajuda endp
;**************************************************************************;
;--------------------------- DECIMALY_INPUT ------------------------------;
;**************************************************************************;
DECIMAL_INPUT PROC
; this procedure will read a number in decimal form
; input : none
; output : store binary number in BX
; uses : MAIN
JMP @READ
@ERROR:
LEA DX, ILLEGAL
MOV AH, 9
INT 21H
call clescr
call calculo

@READ: ; jump label
XOR BX, BX ; clear BX
XOR CX, CX ; clear CX
MOV AH, 1 ; set input function
INT 21H ; read a character
CMP AL, "-" ; compare AL with "-"
JE @MINUS ; jump to label @MINUS if AL="-"
CMP AL, "+" ; compare AL with "+"
JE @PLUS ; jump to label @PLUS if AL="+"
JMP @INPUT ; jump to label @INPUT
@MINUS: ; jump label
MOV CX, 1 ; set CX=1
@PLUS: ; jump label
INT 21H ; read a character
CMP AL, 0DH ; compare AL with CR
JE @END ; jump to label @END if AL=CR
@INPUT: ; jump label
CMP AL, 2eH ; compare AL with 0 mudei de 30h para 2e par aceitar o .
JL @ERROR ; jump to label @ERROR if AL<0
CMP AL, 39H ; compare AL with 9
JG @ERROR ; jump to label @ERROR if AL>9
AND AX, 000FH ; convert ascii to decimal code
PUSH AX ; push AX onto the STACK
MOV AX, 10 ; set AX=10
MUL BX ; set AX=AX*BX
MOV BX, AX ; set BX=AX
POP AX ; pop a value from STACK into AX
ADD BX, AX ; set BX=AX+BX
MOV AH, 1 ; set input function
INT 21H ; read a character
CMP AL, 0DH ; compare AL with CR
JNE @INPUT ; jump to label if AL!=CR

@END: ; jump label
OR CX, CX ; check CX is 0 or not
JE @EXIT ; jump to label @EXIT if CX=0
NEG BX ; negate BX
@EXIT: ; jump label
CMP BX, 0 ; compare BX with 0
JL @ERROR ; jump to label @ILLEGAL if BX<0
CMP BX, 9999 ; compare BX with 9999
JG @ERROR ; jump to label @ILLEGAl if BX>9999


RET ; return control to the calling procedure
DECIMAL_INPUT ENDP
;**************************************************************************;
;--------------------------- DECIMAL_OUTPUT -----------------------------;
;**************************************************************************;
DECIMAL_OUTPUT PROC
; this procedure will display a decimal number
; input : BX
; output : none
; uses : MAIN
CMP BX, 0 ; compare BX with 0
JGE @START ; jump to label @START if BX>=0
MOV AH, 2 ; set output function
MOV DL, "-" ; set DL='-'
INT 21H ; print the character
NEG BX ; take 2's complement of BX
@START: ; jump label
MOV AX, BX ; set AX=BX
XOR CX, CX ; clear CX
MOV BX, 10 ; set BX=10
@REPEAT: ; loop label
XOR DX, DX ; clear DX
DIV BX ; divide AX by BX
PUSH DX ; push DX onto the STACK
INC CX ; increment CX
OR AX, AX ; take OR of Ax with AX
JNE @REPEAT ; jump to label @REPEAT if ZF=0
MOV AH, 2 ; set output function
@DISPLAY: ; loop label
POP DX ; pop a value from STACK to DX
OR DL, 30H ; convert decimal to ascii code
INT 21H ; print a character
LOOP @DISPLAY ; jump to label @DISPLAY if CX!=0
RET ; return control to the calling procedure
DECIMAL_OUTPUT ENDP
;**************************************************************************;
DECIMAL_INPUTteste PROC
; this procedure will read a number in decimal form
; input : none
; output : store binary number in BX
; uses : MAIN
JMP @READ ; jump to label @READ
@ERROR: ; jump label
LEA DX, ILLEGAL ; load and display the string ILLEGAL
MOV AH, 9
INT 21H
call clescr
call calculo

@READ: ; jump label
XOR eBX, eBX ; clear BX
XOR eCX, eCX ; clear CX
MOV AH, 1 ; set input function
INT 21H ; read a character
CMP AL, "-" ; compare AL with "-"
JE @MINUS ; jump to label @MINUS if AL="-"
CMP AL, "+" ; compare AL with "+"
JE @PLUS ; jump to label @PLUS if AL="+"
JMP @INPUT ; jump to label @INPUT
@MINUS: ; jump label
MOV eCX, 1 ; set CX=1
@PLUS: ; jump label
INT 21H ; read a character
CMP AL, 0DH ; compare AL with CR
JE @END ; jump to label @END if AL=CR
@INPUT: ; jump label
CMP AL, 2eH ; compare AL with 0 mudei de 30h para 2e par aceitar o .
JL @ERROR ; jump to label @ERROR if AL<0
CMP AL, 39H ; compare AL with 9
JG @ERROR ; jump to label @ERROR if AL>9
AND eAX, 000FH ; convert ascii to decimal code
PUSH eAX ; push AX onto the STACK
MOV eAX, 10 ; set AX=10
MUL eBX ; set AX=AX*BX
MOV eBX, eAX ; set BX=AX
POP eAX ; pop a value from STACK into AX
ADD eBX, eAX ; set BX=AX+BX
MOV AH, 1 ; set input function
INT 21H ; read a character
CMP AL, 0DH ; compare AL with CR
JNE @INPUT ; jump to label if AL!=CR

@END: ; jump label
OR eCX, eCX ; check CX is 0 or not
JE @EXIT ; jump to label @EXIT if CX=0
NEG eBX ; negate BX
@EXIT: ; jump label
CMP eBX, 0 ; compare BX with 0
JL @ERROR ; jump to label @ILLEGAL if BX<0
CMP eBX, 9999 ; compare BX with 9999
JG @ERROR ; jump to label @ILLEGAl if BX>9999


RET ; return control to the calling procedure
DECIMAL_INPUTteste ENDP
DECIMAL_OUTPUTteste PROC
; this procedure will display a decimal number
; input : BX
; output : none
; uses : MAIN
CMP eBX, 0 ; compare BX with 0
JGE @START ; jump to label @START if BX>=0
MOV AH, 2 ; set output function
MOV DL, "-" ; set DL='-'
INT 21H ; print the character
NEG eBX ; take 2's complement of BX
@START: ; jump label
MOV eAX, eBX ; set AX=BX
XOR eCX, eCX ; clear CX
MOV eBX, 10 ; set BX=10
@REPEAT: ; loop label
XOR eDX, eDX ; clear DX
DIV eBX ; divide AX by BX
PUSH eDX ; push DX onto the STACK
INC eCX ; increment CX
OR eAX, eAX ; take OR of Ax with AX
JNE @REPEAT ; jump to label @REPEAT if ZF=0
MOV AH, 2 ; set output function
@DISPLAY: ; loop label
POP eDX ; pop a value from STACK to DX
OR DL, 30H ; convert decimal to ascii code
INT 21H ; print a character
LOOP @DISPLAY ; jump to label @DISPLAY if CX!=0
RET ; return control to the calling procedure
DECIMAL_OUTPUTteste ENDP

;--------------------------------------------------------------------------;

calculo proc near

lea dx,mens1
mov ah,09h
int 21h

;Call DECIMAL_INPUT
Call DECIMAL_INPUTteste

mov x,ebx

;-----------------Co-Processador---------------
;----------------------------------------------
finit
wait
fild x ; ST(0) = x
fmul x ; ST(0) = ST(0) * x = x*y
fldpi
fmul
;fstsw ax
sahf
fstp temp
lea dx,mens3
mov ah,09h
int 21h

;mov bx,temp
mov ebx,temp
;call DECIMAL_OUTPUT;entra bx
call DECIMAL_OUTPUTteste
jmp exit
calculo endp

exit proc near
lea dx,sair
mov ah,09h
int 21h

call getch
mov cl,al
cmp cl,'N'
jz inicio
cmp cl,'S'
jz fim

cmp cl,'n'
jz menuprincipal
cmp cl,'s'
jz fim

jnz erro2
exit endp
erro2 proc near
call clescr
lea dx,menserro2
mov ah,09h
int 21h
lea dx,prima2
mov ah,09h
int 21h
call getch
jmp exit
erro2 endp
; process overlow error:
;++++++++++++++++++++++ Getchar +++++++++++++++++++++++++++++++++++++++++++++
getch proc near
xor ax,ax
;mov ah,08h
mov ah,01h
int 21h
ret
getch endp

Fim:
call clescr
mov ah,4ch
int 21h
Code Ends
End Inicio

This article has been dead for over six months. Start a new discussion instead.