我尝试计算数学公式
x1 = (radius + (Math.Sin(st)) *4) * Math.Cos(angle * PI / 180);
y1 = (radius + (Math.Sin(st)) * 4) * Math.Sin(angle * PI / 180);
所以我做了这个程序,但出了点问题。我只得到一个Pixel。
org 100h
mov ax, 13h ; AH=0 (Change video mode), AL=13h (Mode)
int 10h ; Video BIOS interrupt
mov ax, 0A000h ; The offset to video memory
mov es, ax ; We load it to ES through AX, becouse immediate operation is not allowed on ES
finit ;inicjalizacja koprocesora :D
call Circle
ret
putpixel:
push cx
push dx ; mul changes dx too
mov cx, 320
mul cx ; multiply Y (ax) by 320 (one row)
add ax, bx ; and add X (bx) (result= dx:ax)
mov di, ax
pop dx
mov [es:di], dl ; store color/pixel
pop cx
ret
Circle:
; x1 = (radius + (Math.Sin(st)) * l*4) * Math.Cos(angle * PI / 180);
; y1 = (radius + (Math.Sin(st)) * l * 4) * Math.Sin(angle * PI / 180);
;stos:st,angle,r,4,pi/180
mov cx,360 ;ilosc powtozren petli rysujacej
tutaj:
add dword[angle],1
fldpi ;wrzucamy PI na stos stos:PI
fild dword[stos180] ;wrzucamy 180 na stos stos: 180,PI
fdivp st1,st0 ;dzielimy 180/PI
fild dword[skok] ;stos:4,pi/180
fild dword[r] ;stos r,4,pi/180
fild dword[angle] ;kąt stos:angle,r,4,pi/180
; x1 = (radius + (Math.Sin(st)) * l*4) * Math.Cos(angle * PI / 180);
fldz ;st stos: st,angle,r,4,pi/180
fsin ;sin(st),angle,r,4,pi/180
fmul st2 ;sin(st)*r,angle,4,pi/180
fmul st2 ;sin(st)*r*4,angle,pi/180
fild dword[l] ;l,sin(st)*r*4,angle,pi/180
fmul st1 ;l*sin(st)*r*4,angle,pi/180
FSTP dword[x] ;angle,pi/180
fmul st1 ;angle*pi/180
fcos ;cos(angle*pi/180)
fld dword[x] ;x,cos(angle*pi/180)
fmul st1 ;x*cos(angle*pi/180)
fistp dword[xf] ; stos pusty
fldpi ;wrzucamy PI na stos stos:PI
fild dword[stos180] ;wrzucamy 180 na stos stos: 180,PI
fdivp st1,st0 ;dzielimy 180/PI
fld dword[skok] ;stos:4,pi/180
fild dword[r] ;stos r,4,pi/180
fild dword[angle] ;kąt stos:angle,r,4,pi/180
; y1 = (radius + (Math.Sin(st)) * l * 4) * Math.Sin(angle * PI / 180);
fldz ;st stos: st,angle,r,4,pi/180
fsin ;sin(st),angle,r,4,pi/180
fmul st2 ;sin(st)*r,angle,4,pi/180
fmul st2 ;sin(st)*r*4,angle,pi/180
FSTP dword[l] ;l,sin(st)*r*4,angle,pi/180
fmul st1 ;l*sin(st)*r*4,angle,pi/180
fistp dword[y] ;angle,pi/180
fmul st1 ;angle*pi/180
fcos ;cos(angle*pi/180)
fld dword[y] ;x,cos(angle*pi/180)
fmul st1 ;x*cos(angle*pi/180)
fistp dword[yf] ; stos pusty
mov ax,word[yf]
mov bx,word[xf]
mov dl,7
call putpixel
loop tutaj
ret
stos180 dd 180.0
angle dd 0.0
skok dd 1.0
xo dd 10.0
yo dd 10.0
l dd 1.0
r dd 10.0
x dd 0.0
y dd 0.0
xf dd 0.0
yf dd 0.0
也许有人知道我做错了什么?
答案 0 :(得分:0)
对我来说,显示我自己的例程(对于MASM +16位链接器)更容易。但它需要80386+,因为它使用32位寄存器和GS和FS段寄存器,并且它还使用一些DOS软件中断来将正弦表加载到空闲存储器位置。我希望它能说清楚如何绘制一个正弦圈。
.MODEL SMALL
.386
.387
Endtab = 900
Grad = 720
Scale = 4
Step = 2
Rad_X = 60h
Rad_Y = 50h
Color = 0Fh
Cr = 0Dh
Lf = 0Ah
Max_X = 320
Max_Y = 200
Video_Seg = 0A000h
Video_Mode = 13h
CODE SEGMENT use16 'CODE'
assume cs:CODE,ds:DATEN,ss:STAPEL
org 100h
START:
mov ax, DATEN
mov ds, ax
call SETFREE ; free all memory
mov bx, 100h ; get 4 KB
call GETSPACE
jc FEHL1
mov [SINSEG], ax
mov gs, ax
mov ax, Video_Seg
mov fs, ax
mov dx, OFFSET SINNAM ; loading sine table
call OPEN
jc FEHL2
xor dx, dx
mov cx, (Endtab+Grad)*8 ; 4 Byte sine/cosine-values
mov ds, SINSEG
call READ
mov ax, DATEN
mov ds, ax
call CLOSE
mov ax, Video_Mode
int 10h
finit
call PIXOFF ; create a table of adresses of each line on screen
xor di, di
;-------------------------------------
CIRCLE:
fld DWORD PTR gs:[di] ; get sine
fimul DWORD PTR[YRAD] ; * Radius
fiadd YM ; plus Y-center
fistp Y ; save Y
fld DWORD PTR gs:[di+Grad]; get cosine(from sine 90 angular degree rotated)
mov bx, Y
fimul DWORD PTR[XRAD]
mov bx, [ebx*2] ; get line address
fiadd XM
fistp X
add di, Scale*Step
add bx, X
mov BYTE PTR fs:[bx], Color
cmp di, Grad*Scale
jb CIRCLE
WAIT:
in al, 60h
test al, 80h
jnz WAIT
;-------------------------------------
mov ax, 3
int 10h
mov ah, 1
int 16h
xor al, al
DOS:
mov ah, 4Ch
int 21h
;----------------------------------------------------------------------------
FEHL1:
mov dx, OFFSET ERTEX1
mov al, 1
TOUT:
mov ah, 9
int 21h
jmp short DOS
;-------------------------------------
FEHL2:
mov dx, OFFSET ERTEX2
mov al, 2
jmp short TOUT
;----------------------------------------------------------------------------
OPEN:
mov ax, 3D00h
int 21h
mov bx, ax
ret
;-------------------------------------
READ:
mov ah, 3Fh
int 21h
ret
;-------------------------------------
CLOSE:
mov ah, 3Eh
int 21h
ret
;----------------------------------------------------------------------------
GETSPACE:
mov ah, 48h
int 21h
ret
;-------------------------------------
SETFREE:
mov bx, ss
mov ax, es
sub bx, ax
mov ax, sp
add ax, 0Fh
shr ax, 4
add bx, ax
mov ah, 4Ah
int 21h
ret
;---------------------------------------------------------------------------
PIXOFF:
xor ax, ax
xor di, di
AGAIN:
mov [di], ax
add di, 2
add ax, Max_X
cmp di, Max_Y * 2
jb AGAIN
ret
CODE ends
;---------------------------------------------------------------------------
DATEN SEGMENT use32 'DATA'
org 0
PIXTAB DW Max_Y dup (0)
X DW ?, ?
Y DW ?, ?
XM DW Max_X/2, 0
YM DW Max_Y/2, 0
XRAD DW Rad_X, ?
YRAD DW Rad_Y, ?
SINSEG DW ? ; segment of sine table
ERTEX1 DB Cr, Lf, "Error, not enough memory aviable", Cr, Lf, "$"
ERTEX2 DB Cr, Lf, "Error, can not load sine table", Cr, Lf
DB "File name: "
SINNAM DB "Sinus.tab", 0, Cr, Lf, "$"
DATEN ends
;---------------------------------------------------------------------------
STAPEL SEGMENT use16 STACK 'STACK'
DB 10h dup (?)
STAPEL ends
end
要创建正弦表:
.MODEL SMALL
.386P
.387
Grad = 720
Endtab = 900
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
DOS:
mov ah, 4Ch
int 21h
;-------------------------------------
TABLE:
xor di, di
TAB:
fldpi
fimul DWORD PTR[I]
fidiv DWORD PTR[TEIL]
fsin
fstp DWORD PTR[di]
inc WORD PTR[I]
add di, 4
cmp WORD PTR[I], Endtab
jnz TAB
ret
;----------------------------------------------------------------------------
MAKDAT:
mov ah, 3Ch
xor cx, cx
int 21h
mov bx, ax
ret
WRITE:
mov ah, 40h
int 21h
ret
CLOSE:
mov ah, 3Eh
int 21h
ret
CODE ends
;---------------------------------------------------------------------------
DATEN SEGMENT use32 'DATA'
org 0
SINTAB DB Endtab DUP (?,?,?,?)
TEIL DW 360, ?
I DW 0, 0
TABNAM DB "Sinus.tab"
DATEN ends
;---------------------------------------------------------------------------
STAPEL SEGMENT use16 STACK 'STACK'
DB 10h dup (?)
STAPEL ends
end