Sinus-Berechnung
Sinus-Berechnung
Hallo,
habe mit dem Co-Prozessor noch nicht viel gemacht.
Nur mal die Quadrat-Wurzel berechnet. also mit:
fild das Quadword geladen. dann
fsqrt aufgerufen
und das Ergebnis mit:
fistp in ein Double-Word geladen
es geht mir darum jetzt den Sinus, bzw. die trigonometrischen Funktionen mittels Co-Prozessor zu erhalten.
Weiß jemand wie das geht?
Danke schon mal im Voraus,
TomCat
habe mit dem Co-Prozessor noch nicht viel gemacht.
Nur mal die Quadrat-Wurzel berechnet. also mit:
fild das Quadword geladen. dann
fsqrt aufgerufen
und das Ergebnis mit:
fistp in ein Double-Word geladen
es geht mir darum jetzt den Sinus, bzw. die trigonometrischen Funktionen mittels Co-Prozessor zu erhalten.
Weiß jemand wie das geht?
Danke schon mal im Voraus,
TomCat
Re: Sinus-Berechnung
Weil die FPU nicht so schnell arbeitet empfielt es sich nach Möglickeit stattdessen Integer-Befehlen der CPU zu verwenden. Die Vorarbeit dazu kann aber die FPU für uns erledigen.TomCat hat geschrieben:Hallo,
habe mit dem Co-Prozessor noch nicht viel gemacht.
Nur mal die Quadrat-Wurzel berechnet. also mit:
fild das Quadword geladen. dann
fsqrt aufgerufen
und das Ergebnis mit:
fistp in ein Double-Word geladen
es geht mir darum jetzt den Sinus, bzw. die trigonometrischen Funktionen mittels Co-Prozessor zu erhalten.
Weiß jemand wie das geht?
Danke schon mal im Voraus,
TomCat
(Ich bin aber nicht so gut darin mathematische Aufgaben zu lösen und tue mich damit selber schwer.)
Mit der folgenden Routine wird eine Sinus/Cosinus-Tabelle mit Integerwerten erstellt und gespeichert.
Diese Tabelle kann dann später von einem anderen Programm geladen und verwendet werden.
Code: Alles auswählen
.MODEL SMALL
.386P
.387
Scale = 4
Grad = 360 * Scale
Endtab = 450 * Scale
Foktor = 10000h
CODE SEGMENT use16 'CODE'
assume cs:CODE,ds:DATEN,ss:STAPEL
;---------------------------------------------------------------------------
org 100h
START: mov ax, DATEN
mov ds, ax
finit
call TABLE
mov dx, OFFSET TABNAM
call MAKDAT
xor dx, dx
mov cx, Endtab*4
call WRITE
call CLOSE
;---------------------------------------------------------------------------
xor al, al ; kein Fehler
DOS: mov ah, 4Ch ; Dos-Rücksprung, Programm-Ende
int 21h
;────────────────────────────────────────────────────────────────────────────
; U N T E R - R O U T I N E N
;────────────────────────────────────────────────────────────────────────────
org START + ((($-START)/16)*16)+16
;─────────────────────────────────────────────────────────────────────────────
; S i n u s - T a b e l l e
;─────────────────────────────────────────────────────────────────────────────
TABLE: xor di, di ; Sinus-Tabelle anlegen
;-------------------------------------
TAB: fldpi ; PI laden
fimul DWORD PTR[I] ; Zaehler mal PI
fidiv DWORD PTR[TEIL] ; durch 180(INT) teilen
fsin ; davon den Sinus
fimul DWORD PTR[FAKT]
fistp DWORD PTR[di] ; in die Sinus-Tabelle schreiben
;-------------------------------------
inc WORD PTR[I] ; Grad-Zähler erhöhen
add di, 4 ; Tabellen-Index erhöhen
cmp WORD PTR[I], Endtab ; Tabellen-Ende erreicht ?
jnz TAB
ret
;─────────────────────────────────────────────────────────────────────────────
org START + ((($-START)/16)*16)+16
;----------------------------------------------------------------------------
MAKDAT: mov ah, 3Ch ; Datei erstellen (ah=3C/5B)
xor cx, cx
int 21h
mov bx, ax
ret
;─────────────────────────────────────────────────────────────────────────────
org START + ((($-START)/16)*16)+16
;----------------------------------------------------------------------------
WRITE: mov ah, 40h ; Datei beschreiben
int 21h
ret
;─────────────────────────────────────────────────────────────────────────────
org START + ((($-START)/16)*16)+16
;----------------------------------------------------------------------------
CLOSE: mov ah, 3Eh ; Datei schließen
int 21h
ret
;---------------------------------------------------------------------------
CODE ends
;────────────────────────────────────────────────────────────────────────────
; D A T E N - B E R E I C H
;────────────────────────────────────────────────────────────────────────────
DATEN SEGMENT use32 'DATA'
org 0
;---------------------------------------------------------------------------
SINTAB DB Endtab DUP (?,?,?,?)
;-------------------------------------
TEIL DW Grad/2, ?
I DW 0, 0
;-------------------------------------
FAKT DD Foktor
;-------------------------------------
TABNAM DB "Sin2Int.tab", 0
DATEN ends
;────────────────────────────────────────────────────────────────────────────
STAPEL SEGMENT use16 STACK 'STACK'
DB 10h dup (?)
STAPEL ends
;────────────────────────────────────────────────────────────────────────────
end
Code: Alles auswählen
.MODEL SMALL
.386
.387
;────────────────────────────────────────────────────────────────────────────
Col = 0C0h
Iter = 456
Xstart = 0
Ystart = 1699
;────────────────────────────────────────────────────────────────────────────
Tast_Port = 60h ; Port-Adresse des Tastatur-Controllers
RGB_Write = 3C8h ; Port-Adresse der Farb-Anteile (write)
;────────────────────────────────────────────────────────────────────────────
CODE SEGMENT use16 'CODE'
assume cs:CODE,ds:DATEN,ss:STAPEL
org 100h
;────────────────────────────────────────────────────────────────────────────
START: mov ax, 13h ; 320 x 200 x 256
int 10h
;-------------------------------------
mov ax, DATEN
mov ds, ax
mov ax, 0A000h
mov es, ax
;-------------------------------------
xor al, al
mov dx, RGB_Write
mov si, OFFSET DAC ; Quelle
mov cx, 0FFh*3
out dx, al ; Farb-Nr. zur VGA-Karte
inc dx ; VGA-PORT der Farb-Anteile (data)
rep outsb ; Farb-Anteile zur Grafik-Karte
;-------------------------------------
finit ; FPU initialisieren
mov DWORD PTR[Z], 100000
mov DWORD PTR[A], 76541
fild A
fidiv Z
fchs
fst A ; -.76548
mov DWORD PTR[B], 76529
fild B
fidiv Z
fchs
fst B ; -.76528
mov DWORD PTR[C], 9986
fild C
fidiv Z
fst C ; .0997
mov DWORD PTR[D], 9990
fild D
fidiv Z
fst D ; .1003
;-------------------------------------
fild NEUN
fidiv ZEHN
fstp PNEUN ; 0.9
;-------------------------------------
fld D
fsub C
fidiv YMAX
fstp G ; G = (D-C)/YMAX
fld B
fsub A
fidiv XMAX
fstp F ; F = (B-A)/XMAX
mov WORD PTR[X1], Xstart
mov WORD PTR[Y1], Ystart
;---------------------------------------------------------------------------
DB 0EAh ; Prefetch-Puffer löschen:
DW (OFFSET BEGINN) ; Die folgenden Zeilen erzeugen
DW SEG CODE ; das Kommando JMP FAR CS:BEGINN
;---------------------------------------------------------------------------
org START + ((($-START)/16)*16)+16 ; Code-Ausrichtung
;---------------------------------------------------------------------------
BEGINN: mov WORD PTR[X], 0
WW1: call FRAK
inc WORD PTR[X]
inc WORD PTR[X1]
cmp WORD PTR[X], 140h
jnz WW1
sbb WORD PTR[X1], 140h
inc WORD PTR[Y1]
;-------------------------------------
lds si, DWORD PTR[COSEG] ; 320 * 200 = 64000 letzte Zeile
xor di, di ; vorletzte Zeile
mov cx, 15920 ; Anzahl Zeilen die gescrollt werden
rep movsd
mov ax, DATEN
mov ds, ax
;-------------------------------------
in al, Tast_Port ; Tasten-Code holen
dec al ; Escape-Taste gedrückt ?
jnz BEGINN
;-------------------------------------
mov ax, 3 ; Text-Mode
int 10h
;-------------------------------------
mov ah, 1 ; Tastatur-Puffer löschen
int 16h
;-------------------------------------
xor al, al ; kein Fehler
DOS: mov ah, 4Ch ; Dos-Rücksprung, Programm-Ende
int 21h
;────────────────────────────────────────────────────────────────────────────
; U N T E R - R O U T I N E N
;────────────────────────────────────────────────────────────────────────────
org START + ((($-START)/16)*16)+16 ; Code-Ausrichtung
;---------------------------------------------------------------------------
FRAK: fld G
mov dx, 1
fimul Y1
fadd C
fst st(1) ; K = G * Y + C
fstp st(2) ; J = K
fld F
fimul X1
fadd A
fst st(3) ; I = F * X + A
fstp st(4) ; H = I
fld st(2-1)
fmul st, st(2)
fstp st(5) ; L = J * J
fld st(4-1)
fmul st, st(4)
fstp st(6) ; M = H * H
FRAK1: cmp dx, Iter ; Iteration
ja short FRAK2
fild ZWEI
fmul st, st(4)
fmul st, st(2)
fadd st, st(1)
fstp st(2) ; J = 2 * H * J + K
fld st(6-1)
fsub st, st(5)
fadd st, st(3)
fstp st(4) ; H = M - L + I
fld st(2-1)
fmul st, st(2)
fstp st(5) ; L = J * J
fld st(4-1)
fmul st, st(4)
fst st(6) ; M = H * H
fadd st, st(5) ; M + L
fadd PNEUN
fistp WW
inc dx
cmp WORD PTR[WW], 5
jb FRAK1
FRAK2: add dx, Col
mov bx, 199
mov di, bx ; 320 Pixel a Zeile
shl bx, 8
shl di, 6
add bx, di
add bx, X ; Y + X
mov BYTE PTR es:[bx], dl ; Farb-Byte schreiben 0-255
ret
;---------------------------------------------------------------------------
CODE ends
;────────────────────────────────────────────────────────────────────────────
; D A T E N - B E R E I C H
;────────────────────────────────────────────────────────────────────────────
DATEN SEGMENT use32 'DATA'
org 0
;---------------------------------------------------------------------------
A DD ?
B DD ?
C DD ?
D DD ?
F DD ?
G DD ?
Z DD ?
X DW ?, ?
Y DW ?, ?
X1 DW ?, ?
Y1 DW ?, ?
XMAX DW 320, ?
YMAX DW 200, ?
ZWEI DD 2
NEUN DD 9
ZEHN DD 10
PNEUN DD ? ; 0.9
WW DW ?, ?
COSEG DW 140h, 0A000h
; rot grün blau
DAC DB 000h,000h,000h ; 0 rot
DB 001h,000h,000h ; 1
DB 002h,000h,000h ; 2
..... gekürzt... im Original werden alle Farbanteile aufgeführt...
DB 0FDh,07Dh,000h ; 3
DB 0FEh,07Eh,000h ; 4
DB 0FFh,07Fh,000h ; 5
;---------------------------------------------------------------------------
DATEN ends
;────────────────────────────────────────────────────────────────────────────
STAPEL SEGMENT use16 STACK 'STACK'
;---------------------------------------------------------------------------
DB 10h dup (?)
;---------------------------------------------------------------------------
STAPEL ends
;────────────────────────────────────────────────────────────────────────────
end
Re: Sinus-Berechnung
Danke funktioniert perfekt !!
Leider fehlen mir die Arcus-Funktionen also Arcus Sinus z.b.
Da scheint es seltsamerweise keinen Co-Prozessor-Befehl zu geben oder täusche ich mich da?
Wie kann man das berechnen?
Leider fehlen mir die Arcus-Funktionen also Arcus Sinus z.b.
Da scheint es seltsamerweise keinen Co-Prozessor-Befehl zu geben oder täusche ich mich da?
Wie kann man das berechnen?
Re: Sinus-Berechnung
Das musss man sich wohl selber ausrechnen lassen.TomCat hat geschrieben:Danke funktioniert perfekt !!
Leider fehlen mir die Arcus-Funktionen also Arcus Sinus z.b.
Da scheint es seltsamerweise keinen Co-Prozessor-Befehl zu geben oder täusche ich mich da?
Wie kann man das berechnen?
Mit folgenden Wörtern "fpu calculate arccos-function" gesucht und gefunden:
Art of Assembly von Randall Hyde
14.5 Sample Program: Additional Trigonometric Functions_
https://courses.engr.illinois.edu/ece39 ... H14-6.html
Dirk
Re: Sinus-Berechnung
asin proc near
fld st(0) ;Duplicate X on tos.
fmul ;Compute X**2.
fld st(0) ;Duplicate X**2 on tos.
fld1 ;Compute 1-X**2.
fsubr
fdiv ;Compute X**2/(1-X**2).
fsqrt ;Compute sqrt(x**2/(1-X**2)).
fld1 ;To compute full arctangent.
fpatan ;Compute atan of the above.
ret
asin endp
brauche die obige Funktion als integer Übergabe und Integer- Resultat damit ich das in einer Integer-Tabelle speichern kann.
Bekomme das nicht hin. Kann mir da einer dabei helfen?
fld st(0) ;Duplicate X on tos.
fmul ;Compute X**2.
fld st(0) ;Duplicate X**2 on tos.
fld1 ;Compute 1-X**2.
fsubr
fdiv ;Compute X**2/(1-X**2).
fsqrt ;Compute sqrt(x**2/(1-X**2)).
fld1 ;To compute full arctangent.
fpatan ;Compute atan of the above.
ret
asin endp
brauche die obige Funktion als integer Übergabe und Integer- Resultat damit ich das in einer Integer-Tabelle speichern kann.
Bekomme das nicht hin. Kann mir da einer dabei helfen?
Re: Sinus-Berechnung
Um Integer-Werte zu bekommen kann man sich das Ergebniss als Integerwert ausgeben lassen. Integer-Befehle sind am "i" im Befehl erkennbar. Mit "fist DWORD PTR[ADRESSE]" wird der Wert als Integerwert in den Speicher geschrieben.TomCat hat geschrieben:asin proc near
fld st(0) ;Duplicate X on tos.
fmul ;Compute X**2.
fld st(0) ;Duplicate X**2 on tos.
fld1 ;Compute 1-X**2.
fsubr
fdiv ;Compute X**2/(1-X**2).
fsqrt ;Compute sqrt(x**2/(1-X**2)).
fld1 ;To compute full arctangent.
fpatan ;Compute atan of the above.
ret
asin endp
brauche die obige Funktion als integer Übergabe und Integer- Resultat damit ich das in einer Integer-Tabelle speichern kann.
Bekomme das nicht hin. Kann mir da einer dabei helfen?
Das macht natürlich nur dann Sinn, wenn der Wert nicht kleiner als 1.0 gross ist. Solche Werte muss man sonst vorher multiplizieren, damit die Nach-Kommastellen vor dem Komma verschoben werden.
Bei der Berechnung selber kann ich dir aber nicht weiter helfen, weil dafür müsste ich es vorher erst selber lernen solche Berechnungen zu verstehen.
...
Wichtig ist es auch darauf ausfzupassen, dass der FPU-Stack nicht überläuft und nicht nur Werte auf den FPU-Stack raufgeschoben werden, sondern die Werte auch wieder vom Stack gepopt werden. Dafür kann man z.B. ein "p" hinter dem "fist-Befehl" anhängen, dann wird der Wert auch vom FPU-Stack entfernt, wenn man den Wert unmittelbar danach nicht mehr in der FPU benötigt.
Dirk
Re: Sinus-Berechnung
hmm, hab einiges versucht, funktioniert leider nicht. kenne mich zu wenig mim Co-Prozessor aus.
Re: Sinus-Berechnung
hab mal folgendes ausprobiert, funzt aber leider nicht.
mov wert1000,1000
fild DWORD PTR[arcussinus_wert] ;von 0-1000
fidiv DWORD PTR[wert1000]
fld st(0)
fmul
fld st(0)
fld1
fsubr
fdiv
fsqrt
fld1
fpatan
fimul DWORD PTR[wert1000]
fistp DWORD PTR[winkel_wert]
:ende
Jemand ne Idee??
mov wert1000,1000
fild DWORD PTR[arcussinus_wert] ;von 0-1000
fidiv DWORD PTR[wert1000]
fld st(0)
fmul
fld st(0)
fld1
fsubr
fdiv
fsqrt
fld1
fpatan
fimul DWORD PTR[wert1000]
fistp DWORD PTR[winkel_wert]
:ende
Jemand ne Idee??
Re: Sinus-Berechnung
Wofür sind die "fld st(0)" ?TomCat hat geschrieben:hab mal folgendes ausprobiert, funzt aber leider nicht.
mov wert1000,1000
fild DWORD PTR[arcussinus_wert] ;von 0-1000
fidiv DWORD PTR[wert1000]
fld st(0)
fmul
fld st(0)
fld1
fsubr
fdiv
fsqrt
fld1
fpatan
fimul DWORD PTR[wert1000]
fistp DWORD PTR[winkel_wert]
:ende
Jemand ne Idee??
Am besten noch einmal genau nachlesen im:
Intel® 64 and IA-32 Architectures Software Developer's Manuals.pdf
http://download.intel.com/design/proces ... 253665.pdf
[Chapter 3 Instruction Set Reference A - M]
->[3.1 Interpreting the Instruction Reference Pages]
->->[3.2 Instruction (A - M)]
FPATAN-Partial Arctangent Vol. 2A Seite 3-389
Dirk