flat assembler
Message board for the users of flat assembler.

flat assembler > DOS > Floating point numbers

Author
Thread Post new topic Reply to topic
A$M



Joined: 29 Feb 2012
Posts: 94
Hello all!

I would know how to use floating point numbers in Assembly. I do not understand almost nothing about it. So if anyone has some spare time, please teach me how to use them or where to learn about them (I could not understand the FASM documentation).
Post 25 Feb 2013, 21:05
View user's profile Send private message Reply with quote
AsmGuru62



Joined: 28 Jan 2004
Posts: 1388
Location: Toronto, Canada
I learned here:
http://www.website.masmforum.com/tutorials/fptute/
Great article about float point processing!

So, what kind of problem you're trying to solve?
Most of the difficulty are conversions to/from text:

TEXT -> FLOAT POINT REGISTER
FLOAT POINT REGISTER -> TEXT

The rest is just watching over the FPU stack so it would not overflow.
Please ask your questions -- I'll try to help.
Post 25 Feb 2013, 22:02
View user's profile Send private message Send e-mail Reply with quote
A$M



Joined: 29 Feb 2012
Posts: 94
AsmGuru62 wrote:
I learned here:
http://www.website.masmforum.com/tutorials/fptute/
Great article about float point processing!

So, what kind of problem you're trying to solve?
Most of the difficulty are conversions to/from text:

TEXT -> FLOAT POINT REGISTER
FLOAT POINT REGISTER -> TEXT

The rest is just watching over the FPU stack so it would not overflow.
Please ask your questions -- I'll try to help.


Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you!!! It's too easy...

A little program:
Code:
org 100h use16 finit fld [num3] fld [num1] fld [num2] fmul ST0, ST1 fcom ST2 fstsw ax fwait sahf jpe error jne no mov al, "Y" jmp @f no: mov al, "N" @@: mov ah, 0Eh int 10h exit: xor ax, ax int 16h ret error: mov ah, 0Eh mov al, "E" int 10h jmp exit num1 dt 1.01 num2 dt 5.5 num3 dt 5.555


It returns Y if "1.01*5.5=5.555", else returns N.
Post 26 Feb 2013, 21:05
View user's profile Send private message Reply with quote
AsmGuru62



Joined: 28 Jan 2004
Posts: 1388
Location: Toronto, Canada
So, it works?!
Post 26 Feb 2013, 22:24
View user's profile Send private message Send e-mail Reply with quote
A$M



Joined: 29 Feb 2012
Posts: 94
AsmGuru62 wrote:
So, it works?!


Works. Now, another program more complicated, but simple, which makes a circle. Please compile it and tell your opinion. I'm 13 years old and had to search for things I did not understand. That is, if there are any errors, please tell me. Anyone can copy, modify, print or do anything else.

Code:
org 100h use16 mov ax, 13h int 10h finit mov ax, 0A000h mov es, ax next: call calculate mov cx, [x] mov dx, [y] call drawPixel inc [degrees] cmp [degrees], 360;ยบ jne next mov ax, 0 int 16h ret drawPixel: ; CX and DX = X and Y add cx, 70 add dx, 70 mov ax, dx shl dx, 6 shl ax, 8 add dx, ax mov bx, cx add bx, dx mov byte[es:bx], 15 ret calculate: ffree st7 ffree st6 ffree st5 ffree st4 ffree st3 fild [radius] fild [halfcircle] fild [degrees] fldpi fmul st0, st1 fdiv st0, st2 fsincos fmul st0, st4 fistp [x] fmul st0, st3 fist [y] ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Formulas ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Degrees (x) -> Radians = x pi/180 ;; ;; Degrees (x) Radius (r) -> X location = r cos(x) ;; ;; Degrees (x) Radius (r) -> Y location = r sin(x) ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; radius dw 25 degrees dw 0 halfcircle dw 180 x dw ? y dw ?


EDIT: It is dotted circles if the radius is large. No big issue. The solution would be to draw lines between the points, but it is unnecessary.
Post 27 Feb 2013, 19:43
View user's profile Send private message Reply with quote
AsmGuru62



Joined: 28 Jan 2004
Posts: 1388
Location: Toronto, Canada
Nice code.
I see just few things:

1. The way you return to DOS is most likely incorrect.
I think is the way you do it:
Code:
mov ax,0 int 16h ret

That RET opcode may not work if you will run your program from standard DOS command line.
The proper way to stop the COM program is INT 20h:
Code:
mov ax,0 int 16h int 20h

2. You can make it faster by only computing the pixels for 1/4 of a circle, because
the other 3/4 are a symmetrically positioned pixels just with oppisite sign for X and Y.
This way you need to perform only 25% of the pixels calculation.

3. You can even speed up more by not using degrees, but radians.
The circle takes up 2*PI in radians, meaning that you need a 1/360th part of it to be a 1 degree.
Create a variable and set it to (2*PI)/360 and use it as a step to increment your radian value going from 0 to 90, so you avoid the conversion on every step.
Post 27 Feb 2013, 20:11
View user's profile Send private message Send e-mail Reply with quote
freecrac



Joined: 19 Oct 2011
Posts: 117
Location: Germany Hamburg
AsmGuru62 wrote:
Nice code.
I see just few things:

1. The way you return to DOS is most likely incorrect.
I think is the way you do it:
Code:
mov ax,0 int 16h ret

That RET opcode may not work if you will run your program from standard DOS command line.
The proper way to stop the COM program is INT 20h:
[code]
mov ax,0
int 16h
int 20h

But if we start a *.com-file under pure DOS and from the standard DOS command line, then DOS fill the PSP with an int 20h instruction and additional the stack starts with a word of 0000.
So if we terminate our application only with a ret-instruction, then our programmcounter will be set to this int 20h instruction inside of the PSP.
(adopted unix like ret-methode in MSDOS 2 and above?)

I can not see a big differce between using only a ret-instruction for to execute the int 20h instruction inside of the PSP, or to execute an int 20h instruction that was placed as the last instruction in our codesegment.
And i never read it before that there is a problem using only a ret instruction or that it is not a proper way for to stop a COM program.
The only normaly conditions are that we do not have to pop the last word from the stack and we do not have to corrupt the PSP structure and additional CS normaly pointed to our codesegment.

I need more information and a clarification about the difference and the statement that it is not a propper way. What does it means exactly?

Dirk
Post 28 Feb 2013, 07:41
View user's profile Send private message Send e-mail Reply with quote
AsmGuru62



Joined: 28 Jan 2004
Posts: 1388
Location: Toronto, Canada
Cool! I did not know (or just forgot) that about the PSP having INT 20h opcode.
I guess both RET and INT 20h would be fine to end a COM program.
Post 28 Feb 2013, 15:20
View user's profile Send private message Send e-mail Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
AsmGuru62 wrote:
I guess both RET and INT 20h would be fine to end a COM program.
Unless you're fiddling with cs. Those ret, int20 and int21/00 methods are highly dependent on it, they're remnants of CP/M legacy (call/jmp 0 for program termination, call 5 for BDOS services, and CCP pushes 0 on stack). Once TSRs were introduced, DOS should know which process to terminate (guess why we do need int21/50 "set current PID/PSP").
Post 28 Feb 2013, 18:41
View user's profile Send private message Reply with quote
freecrac



Joined: 19 Oct 2011
Posts: 117
Location: Germany Hamburg
Good morning and many thanks for posting an answer.

I think our last instruction in the codesegment of a COM-executacle is also highly dependent on CS, no matter if it is a ret-instruction or an int 20h-instruction, because all together have to be in one 64 KB segment with the PSP.
So if we fiddiing with CS before, then we become a problem with both instructions.

But if we lost the address, then we can get back the address of the currrent PSP:
RBIL->inter61b.zip->INTERRUP.H
Code:
--------D-2162------------------------------- INT 21 - DOS 3.0+ - GET CURRENT PSP ADDRESS AH = 62h Return: BX = segment of PSP for current process Notes: this function does not use any of the DOS-internal stacks and may thus be called at any time, even during another INT 21h call the current PSP is not necessarily the caller's PSP identical to the undocumented AH=51h

Dirk
Post 01 Mar 2013, 08:12
View user's profile Send private message Send e-mail Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >

Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 2004-2018, Tomasz Grysztar.

Powered by rwasa.