【问题标题】:Graph drawing in YASM 8086YASM 8086 中的图形绘制
【发布时间】:2022-12-05 06:26:57
【问题描述】:

我不知道是否有人能够帮助我,但我会尽可能清楚地解释我的问题。我正在使用 YASM 学习 8086 FPU。我想画画y = cos(x^2+x+1)This is how this graph looks like。我是在 DosBox 中做的,我正在模拟 8086 处理器。

我的问题:如何标准化图形的(红色)比率,以便在 DosBox 中可读。

到目前为止,我设法绘制了一个坐标平面。而且我想我设法绘制了这张图,但是比例太小无法检查它是否真的很好。这是到目前为止的样子GRAPH IMAGE](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 如果有帮助

【问题讨论】:

    标签: assembly graph x86 fpu yasm


    【解决方案1】:

    轴是简单的部分

    由于您在分辨率为 320 x 200 的图形屏幕上工作,因此 X 坐标的范围为 0 到 319,Y 坐标的范围为 0 到 199。您的代码错误地输出了 X 的 320 和 y 的 200,而您没有不要使用 0 的 X 或 0 的 Y。

         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 指令正在处理存储在内存中的值,但这样做的方式不兼容!例如。价值1不能同时是整数双字和单精度浮点数。您使用 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,但将此值存储在整数内存变量中只会产生 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]
    

    【讨论】:

      猜你喜欢
      • 2022-11-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-23
      相关资源
      最近更新 更多