我不知道是否有人能帮我,但我会尽量清楚地解释我的问题。我正在用YASM学习8086 FPU。我想画y= cos(x^2+x+1) 这就是这张图的样子。我正在用DosBox做这件事,我正在模拟8086处理器。
My problem:如何规范图形的(红色)比率,这样就可以在DosBox中阅读。
到目前为止,我成功地画了一个坐标平面。我想我已经画出了这个图表,但是这个比率太小了,无法检查它是否真的很好。到目前为止,图形图像](https://i.stack.imgur.com/0Hy6X.jpg)就是这样的。
我用FPU计算Y坐标。我用堆栈来计算Y坐标。X坐标将从320到0(使用dec si),正如您在我的代码中看到的那样。
在这个代码中,我试图计算不同X (si)的Y (di)。把像素放在点上,它必须在其中。
;------------------------------------------------------------------------
%include 'yasmmac.inc'
org 100h
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
section .text ; Code starts here
startas:
call procSetGraphicsMode
;;;;;;;;;;;;;;;;;;;;;;;;; COORDINATE PLANE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
mov di, 200
mov si, 160
.vertical:
mov cl, 15
call procPutPixel
dec di
jnz .vertical
mov si, 320
.horizontal:
mov di, 100
mov cl, 15 ; 15 = white color
call procPutPixel
dec si
jnz .horizontal
; y = di
; x = si
mov si, 320
mov di, 100
;;;;;;;;;;;;;;;;;;;;;;;; GRAPH ;;;;;;;;;;;;;;;;;;;;;;;;
.loop:
mov [value1], si
mov [value2], si
finit
fild dword [value1]
fild dword [value1]
fild dword [value3] ; move to stack 1
fmul dword [value1]
fadd st0, st1 ; add x in stack head
fadd st0, st3 ; add 1 in stack head
fcos ; cos(x^2 + x + 1)
frndint ; round
fistp word [y] ; Load rounded answer to [y] variable
add di, [y] ; Add [y] to di
mov cl, 4 ; 4 = Red color
call procPutPixel
dec si
jnz .loop
;;;;;;;;;;;;;;;;;;;;;;;; WAIT FOR ESC ;;;;;;;;;;;;;;;;;;;;;;;;
call procWaitForEsc
exit
%include 'yasmlib.asm'
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
section .data ; data
value1:
dd 0.0
value2:
dd 0.0
value3:
dd 1.0
xc:
dw 160
yc:
dw 100
x:
dw 0
y:
dw 0
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
section .bss yasmlim.asm如果有帮助的话
发布于 2022-12-04 22:04:19
轴是容易的部分。
由于您正在使用分辨率为320 x 200的图形屏幕,X坐标范围从0到319,Y坐标范围从0到199。您的代码错误地输出了X的320和y的200,并且没有使用X的0或Y的0。
xor di, di ; Y
.vertical:
mov si, 160 ; X
mov cl, 15 ; Color
call procPutPixel
inc di
cmp di, 199 ; MaxY
jbe .vertical
xor si, si ; X
.horizontal:
mov di, 100 ; Y
mov cl, 15 ; Color
call procPutPixel
inc si
cmp si, 319 ; MaxX
jbe .horizontal
; y = di
; x = si
mov si, 320
mov di, 100数据定义
value1: dd 0.0 value2: dd 0.0 value3: dd 1.0
您的FPU指令正在处理存储在内存中的值,但它们是以不兼容的方式进行的!例如:value1不能同时成为整数dword和单个精度浮动。您使用16位整数寄存器SI中的值启动了这个变量,因此将其处理为16位整数。
valueX: dw 0计算
finit (最好使用非等待的fninit)最好保持在循环之外。
frndint是多余的,因为fistp word [y]会自动为您执行舍入操作。
fmul st0可以使st0的值平方。
fld1可以将值1加载到FPU堆栈。不需要基于内存的变量,也不需要为每个X重新加载它。
xor si, si ; X
fninit
fld1 ; CONST 1
.loop:
mov [valueX], si ; X
fild word [valueX] ; st0 = X
fmul st0 ; st0 = X^2
fiadd word [valueX] ; st0 = X^2 + X
fadd st0, st1 ; st0 = X^2 + X + 1
fcos ; st0 = cos(X^2 + X + 1) [-1,+1]
...
fistp word [y] ; {-1,0,+1}
mov di, 100 ; Y
add di, [y] ; -> Y={99,100,101}
mov cl, 4 ; Color
call procPutPixel
inc si
cmp si, 319
jbe .loop
fstp ; Clean FPU stack, removing the CONST 1使输出具有可读性
FPU传递的余弦值介于-1到+1之间,但将该值存储在整数内存变量y中将产生3个离散值-1、0和+1。
我们需要的是将余弦缩放成某种因子,比如60。
将其添加到数据中:
scaleY: dw 60在省略号处添加fimul word [scaleY],生成:
fcos ; st0 = cos(X^2 + X + 1) [-1,+1]
fimul word [scaleY] ; st0 = cos(X^2 + X + 1) * 60
fistp word [y] ; [-60,+60]
mov di, 100 ; Y
add di, [y] ; -> Y=[40,160]https://stackoverflow.com/questions/74640974
复制相似问题