Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Floating point exception

930 views
Skip to first unread message

spam...@crayne.org

unread,
Oct 20, 2005, 9:11:57 PM10/20/05
to
Hello.. I am just a beginner with assembly, hope I found the right
group?
This is my program I am just trying to divide whatever is input from
the keyboard by 10, I can hard code values to be in ax but my variable
wont work. There is probably something really simple I hope but I am
lost here.
Error message I get: Floating point exception

Thanks!


section .data

varinput dw ' ',0xA
leninput equ $ - varinput
varquotient db 1
varremainder db 1

section .text

global main

main:

;read keyboard input
mov eax,3
mov ebx,0
mov ecx,varinput
mov edx,leninput ;2;leninput
int 0x80

;print varinput
mov eax,4
mov ebx,1
mov ecx,varinput
mov edx,leninput
int 0x80

;ax = ax/10
mov ax,[varinput] ; 0,1,2.. works: problem with this??
mov cl,10
div cl ; floating point exception here??

; printing stuff I removed to shorten plea 4 help

;system exit:
mov eax,1
mov ebx,0
int 0x80

Tim Roberts

unread,
Oct 21, 2005, 12:21:28 AM10/21/05
to
spam...@crayne.org wrote:
>
>Hello.. I am just a beginner with assembly, hope I found the right
>group?
>This is my program I am just trying to divide whatever is input from
>the keyboard by 10, I can hard code values to be in ax but my variable
>wont work. There is probably something really simple I hope but I am
>lost here.

>;read keyboard input
>mov eax,3
>mov ebx,0
>mov ecx,varinput
>mov edx,leninput ;2;leninput
>int 0x80

This reads two characters from stdin and stores them at varinput, in ASCII.
If you type "10", you get two ASCII characters. "1" in ASCII is hex 31,
and "0" is hex 30. So, [varinput] will contain hex 3031 (remember
endianness), which is 12,337 in decimal.

>;ax = ax/10
>mov ax,[varinput] ; 0,1,2.. works: problem with this??
>mov cl,10
>div cl ; floating point exception here??

Now you take 12,337 and try to divide by 10. The resulting quotient will
not fit into an 8-bit result, so you get a divide overflow, which produces
a divide exception.

When you are working with numbers, you need to get really familiar with
routines that convert from ASCII to binary and back. For this particular
example, try:

mov ax, [varinput]
sub ax, 3030h
aad
mov cl, 10
div cl

The "aad" trick only works for two-digit numbers. Note that you will have
to convert the value in al BACK to ASCII for printing:

aam
add ax, 3030h
xchg ah, al

Now you can store ax into a string for printing.
--
- Tim Roberts, ti...@probo.com
Providenza & Boekelheide, Inc.

Dirk Wolfgang Glomp

unread,
Oct 21, 2005, 1:12:07 AM10/21/05
to
spam...@crayne.org schrieb:

> Hello.. I am just a beginner with assembly, hope I found the right
> group?

Yes, here is the correct place to ask about assembly.

> This is my program I am just trying to divide whatever is input from
> the keyboard by 10, I can hard code values to be in ax but my variable
> wont work. There is probably something really simple I hope but I am
> lost here.
> Error message I get: Floating point exception

I dont believe that the error-text is correct,
because you dont use any floating point instruction.

> section .data
>
> varinput dw ' ',0xA
> leninput equ $ - varinput
> varquotient db 1
> varremainder db 1
>
> section .text
>
> global main
>
> main:
>
> ;read keyboard input
> mov eax,3
> mov ebx,0
> mov ecx,varinput
> mov edx,leninput ;2;leninput
> int 0x80
>
> ;print varinput
> mov eax,4
> mov ebx,1
> mov ecx,varinput
> mov edx,leninput
> int 0x80
>
> ;ax = ax/10
> mov ax,[varinput] ; 0,1,2.. works: problem with this??
> mov cl,10
> div cl ; floating point exception here??

It is not a floating point operation, it is pur integer.
To use a floating point divide, use the fdiv instruction.

I think your integer-divide need to clear the dx-register,
before the div-command(maybe xor dx,dx).

> ; printing stuff I removed to shorten plea 4 help
>
> ;system exit:
> mov eax,1
> mov ebx,0
> int 0x80

I dont know about the used soft-ints.
In the future i will start to assamble under linux,
just i am a pur DOS-programmer.

Dirk

spam...@crayne.org

unread,
Oct 21, 2005, 1:16:12 PM10/21/05
to
Thanks for the help from both of you

That trick you described I did get to work but it is still beyond my
level of understanding..

The clearing of the dx register didnt seem to solve it but I have used
it before in such a case.

spam...@crayne.org

unread,
Oct 21, 2005, 1:16:08 PM10/21/05
to
I remember that xor to clear registries but it doesnt work in this
case.

I did get that "aad" trick to work but it is over my head on
understanding at this point, more research for me I suppose.

Frank Kotler

unread,
Oct 21, 2005, 5:16:18 PM10/21/05
to
spam...@crayne.org wrote:
> Hello.. I am just a beginner with assembly, hope I found the right
> group?
> This is my program I am just trying to divide whatever is input from
> the keyboard by 10,

Everything but the last character entered is the quotient, the last
character entered is the remainder. Problem solved. But I suppose you
want a somewhat more "general" routine than just dividing by ten...
sigh... :)

> I can hard code values to be in ax but my variable
> wont work. There is probably something really simple I hope but I am
> lost here.

Yeah, the answer to that is in how the "div" instruction works.

> Error message I get: Floating point exception

A machine I used to have reported this error as "divide by zero". (No I
didn't! I divided by ten!!!). "Floating point exception" is just as bad
- you didn't use any floating point instructions! It's really an
"overflow" condition - the result of the division won't fit in the
(implied) destination register.

div cl ; divides ax (or ah:al) by cl - al, remainder ah
div cx ; divides dx:ax by cx - ax, remainder in dx
div ecx ; divides edx:eax by ecx - eax, remainder in edx

This is the same problem that could be solved by "clear dx", but it's ah
that you need to clear in this case. Doesn't actually need to be
"cleared", but it needs to be less than cl...

The "aad"/"aam" trick Tim showed you is good for two digits. This raises
the question of how big a number do you want to be able to handle? Two
digits will take you up to 99, 8 bits will go to 255. 32 bits to about 4
billion. Bigger than that gets harder. Infinity is not an option :)

> Thanks!

You're welcome.

> section .data
>
> varinput dw ' ',0xA
> leninput equ $ - varinput

You'd want to make this buffer bigger if you wanted to handle more than
two digits, of course. You don't really need the linefeed in there, and
you might want it to be "db", not "dw".

> varquotient db 1

Might want more room here, too, if doing more than two digits.

> varremainder db 1

The remainder will only be one digit. Might want to stick that linefeed
in here(?).

> section .text
>
> global main
>
> main:
>
> ;read keyboard input
> mov eax,3
> mov ebx,0
> mov ecx,varinput
> mov edx,leninput ;2;leninput

Yeah :) "leninput" isn't really 2, it's 4 - 'cause you declared the
buffer "dw"... You probably *do* want to leave room for the linefeed
sys_read will add.

> int 0x80
>
> ;print varinput
> mov eax,4
> mov ebx,1
> mov ecx,varinput
> mov edx,leninput
> int 0x80
>
> ;ax = ax/10
> mov ax,[varinput] ; 0,1,2.. works: problem with this??

0, 1, 2... all clear ah. "mov ax, [varinput]" puts a value in ah that's
going to cause the overflow.

> mov cl,10
> div cl ; floating point exception here??

Actually, you've got to multiply some before you're ready to div. You've
got the input in the form of ascii characters representing decimal
digits (if the user behaved). You need to convert this string og ascii
characters to a number before you can do arithmetic on it (with the
exception of the divide by ten "cheat" I mentioned). The "aad trick"
does this for two digits. A more "general" method is:

Zero out a "result" register.
Top:
Get first/next character.
Verify that it's valid.
Convert from ascii digit to number. (sub '0')
Multiply result by ten.
(check for overflow)
Add in the new digit.
(check for overflow)
Repeat from "Top:"

Now you've got a number you can divide by ten - or something else.

> ; printing stuff I removed to shorten plea 4 help

Okay, but you've got to reverse the above process to get from a number,
back to a string of ascii digits you can print. You could reuse the
input buffer for this, but it might be clearer to define a separate
output buffer. Since the remainder will be just one digit, it's easy -
just add '0'. If the quotient's just one digit, it's easy too - but you
probably want to do more.

> ;system exit:
> mov eax,1
> mov ebx,0
> int 0x80

The "Linux parts" of your program look good. Nice to see folks using
Linux to learn asm!

Best,
Frank

Dirk Wolfgang Glomp

unread,
Oct 21, 2005, 5:34:50 PM10/21/05
to
spam...@crayne.org schrieb:

I think the problem is, to convert some ascii values to one register/mem
and second to convert one value in a register,
to some ascii-digits to print on screen.

Is it correct and do you want a decimal output?

Dirk

Dirk Wolfgang Glomp

unread,
Oct 21, 2005, 6:09:25 PM10/21/05
to
Frank Kotler schrieb:

[...]

...excellence vibration.

Dirk

spam...@crayne.org

unread,
Oct 23, 2005, 11:57:22 PM10/23/05
to

What?


Yes I do want decimal output.

I am really new to assembly and I find it hard to find good tutorials
on the web and when I do they are DOS based. Would anyone recommend
buying a book or is the internet better?

Sorry I haven't gotten back to this, I dont know if it is even going to
be an assignment :)

I am studying for an assembly test.

Wanted to say thanks to everyone for the many replies. Thanks!

Dirk Wolfgang Glomp

unread,
Oct 24, 2005, 6:04:07 AM10/24/05
to
spam...@crayne.org schrieb:

>>Frank Kotler schrieb:
>>
>>[...]
>>
>>...excellence vibration.
>
> What?
>
> Yes I do want decimal output.
>
> I am really new to assembly and I find it hard to find good tutorials
> on the web and when I do they are DOS based.

I think Franks answer is not DOS based.
He shows all the importend things, of your used instructions.
Only the soft-irqs on a Linux based OS are different from DOS.

> Would anyone recommend
> buying a book or is the internet better?

I dont know.
I start to learn assembly on a C64, with three 8 Bit-register.
Then i change to the 286-pc without FPU.
The first thing that i must learn, was the segmentation.
All others stuff was not so the different,
between the C64 and the x86(RM).
And before i learn any DOS-command and before i use a gui,
i write my first mnemonics with debug.exe.
Then i buy the german Data Becker book "PC-Intern".

> Sorry I haven't gotten back to this, I dont know if it is even going to
> be an assignment :)

Here is nothing to shame.
If you dont understand a part of our answers, please ask again.

Sorry for my bad english, the biggest part of english
i learn on a computer and not at our german school.

Dirk

0 new messages