汇编程序和协处理器

时间:2014-09-08 17:50:48

标签: assembly graph x86

我尝试计算数学公式

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

也许有人知道我做错了什么?

1 个答案:

答案 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