You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

8086汇编实现曼德博集合渲染与示例不符的排查求助

曼德博集合渲染问题排查求助

这是此前一则帖子的续篇,我们正在使用DOSBox搭配8086包与MASM完成汇编语言作业,需在DOSBox屏幕上渲染曼德博集合近似图形,具体要求如下:

  • 禁止使用栈,采用scale=64的定点数
  • 屏幕25行×80列的每个单元格对应复数点 c = c_x + i * c_y,其中:
    • c_x = -144 + col * 3(0 ≤ col ≤ 79)
    • c_y = -72 + row * 6(0 ≤ row ≤ 24)
  • 迭代计算规则:
    对每个点递归计算 z_{n+1} = z_{n} ^ 2 + c,简化为以下两个公式:
    x_new = x ^ 2 / 64 - y ^ 2 / 64 + c_x
    
    y_new = x * y / 32 + c_y
    
  • 迭代限制与逃逸条件:最多迭代16次,当满足 x^2/64 + y^2/64 > 4*64(即256)时判定为逃逸
  • 渲染规则:
    • 1-3次迭代逃逸:输出012Eh
    • 4-7次迭代逃逸:输出042Ah
    • 8-15次迭代逃逸:输出0EDBh
    • 16次未逃逸:输出0ADBh

教师提供了预期效果图,但我编写的代码生成的图形与示例存在30个差异单元格(呈轴对称,共15组)。我已按照教师给出的伪代码调整代码,仍未得到正确结果;还制作了Excel表格手动计算,结果与我的代码一致,但与教师示例不符。作业采用自动评分机制,只要有一个单元格不符即得0分,我和多数同学都遇到此问题,请求排查原因。

附两次尝试的代码

CODE #1

.model small
.stack 100h
.data
    ; We store our variables in memory because the 8086 processor 
    ; does not have enough registers to hold everything at once.
    c_x     dw 0    
    c_y     dw 0
    x       dw 0
    y       dw 0
    x_sqr   dw 0
    y_sqr   dw 0
    row_cnt dw 0
    col_cnt dw 0
    iter    dw 0

.code
START:
    ; clearing the dos screen
    mov ax, 0003h
    int 10h
    
    ; writing to the data segment our screen coordinates for the horizontal axis and setting di=0
    mov ax, @data
    mov ds, ax
    mov ax, 0B800h
    mov es, ax
    mov di, 0

    ; setting up the row loop
    mov c_y, -72
    mov row_cnt, 25

ROW_LOOP:
    ; setting up the colum loop
    mov c_x, -144
    mov col_cnt, 80

COL_LOOP:
    ; initial values of x,y from z_0
    mov x, 0
    mov y, 0
    mov iter, 0

MANDEL_LOOP:
    ; escape condition
    cmp iter, 16
    je MANDEL_SET
    
    ; calculating x^2/64
    mov ax, x
    imul x              ; DX:AX = x * x
    mov bx, 64
    idiv bx             ; AX = (DX:AX) / 64
    mov x_sqr, ax

    ; calculating y^2/64
    mov ax, y
    imul y              ; DX:AX = y * y
    mov bx, 64
    idiv bx             ; AX = (DX:AX) / 64
    mov y_sqr, ax

    ; calc saving y_new = (xy) / 32 + c_y
    mov ax, x
    imul y              ; DX:AX = x * y
    mov bx, 32
    idiv bx             ; AX = (DX:AX) / 32
    add ax, c_y
    mov y, ax

    ; calc saving x_new = x_sqr - y_sqr + c_x
    mov ax, x_sqr
    sub ax, y_sqr
    add ax, c_x
    mov x, ax
    
    inc iter    
        
    ; escape condition ; back to line 63
    mov ax, x
    imul x
    mov cx, 64
    idiv cx
    mov bx, ax          ; bx now has x^2/64
    mov ax, y
    imul y
    idiv cx             ; ax now has y^2/64
    add ax, bx
    cmp ax, 256
    jg DRAW_CELL
    
    jmp MANDEL_LOOP
    
MANDEL_SET:
    ; it survived 16 iterations so we draw the solid green block.
    mov ax, 0ADBh
    jmp WRITE_VRAM

WRITE_VRAM:
    ; printing to the screen the char
    mov es:[di], ax     
    add di, 2           ; move forward 2 bytes in video memory

    ; moving to next colum
    add c_x, 3          
    dec col_cnt
    jz COL_DONE
    jmp COL_LOOP
COL_DONE:

    ; moving to next row
    add c_y, 6          
    dec row_cnt
    jz ROW_DONE
    jmp ROW_LOOP
ROW_DONE:

    jmp EXIT

DRAW_CELL:
    ; assigning the printed char based of iter value
    cmp iter, 3
    jle COL_1_3
    cmp iter, 7
    jle COL_4_7

    ; if it didnt jump, iter is 8-15
    mov ax, 0EDBh
    jmp WRITE_VRAM

COL_1_3:
    mov ax, 012Eh
    jmp WRITE_VRAM
COL_4_7:
    mov ax, 042Ah
    jmp WRITE_VRAM
    
EXIT:
    ; moving the command line to the bottom and exiting the program
    mov ah, 02h
    mov bh, 00h
    mov dh, 18h
    mov dl, 00h
    int 10h
    
    mov ah, 04Ch
    int 21h

END START

CODE #2

.model small
.stack 100h
.data
    ; We store our variables in memory because the 8086 processor 
    ; does not have enough registers to hold everything at once.
    c_x     dw 0    
    c_y     dw 0
    x       dw 0
    y       dw 0
    x_sqr   dw 0
    y_sqr   dw 0
    row_cnt dw 0
    col_cnt dw 0
    iter    dw 0

.code
START:
    ; clearing the dos screen
    mov ax, 0003h
    int 10h
    
    ; writing to the data segment our screen coordinates for the horizontal axis and setting di=0
    mov ax, @data
    mov ds, ax
    mov ax, 0B800h
    mov es, ax
    mov di, 0

    ; setting up the row loop
    mov c_y, -72
    mov row_cnt, 25

ROW_LOOP:
    ; setting up the colum loop
    mov c_x, -144
    mov col_cnt, 80

COL_LOOP:
    ; initial values of x,y from z_0
    mov x, 0
    mov y, 0
    mov iter, 0

MANDEL_LOOP:
    ; escape condition
    cmp iter, 16
    je MANDEL_SET
    
    ; calculating x^2/64
    mov ax, x
    imul x              ; DX:AX = x * x
    mov bx, 64
    idiv bx             ; AX = (DX:AX) / 64
    mov x_sqr, ax

    ; calculating y^2/64
    mov ax, y
    imul y              ; DX:AX = y * y
    mov bx, 64
    idiv bx             ; AX = (DX:AX) / 64
    mov y_sqr, ax

    ; escape condition ; back to line 63
    mov ax, x_sqr
    add ax, y_sqr
    cmp ax, 256
    jg DRAW_CELL
    
    ; calc saving y_new = (xy) / 32 + c_y
    mov ax, x
    imul y              ; DX:AX = x * y
    mov bx, 32
    idiv bx             ; AX = (DX:AX) / 32
    add ax, c_y
    mov y, ax

    ; calc saving x_new = x_sqr - y_sqr + c_x
    mov ax, x_sqr
    sub ax, y_sqr
    add ax, c_x
    mov x, ax
    
    inc iter        
    jmp MANDEL_LOOP
    
MANDEL_SET:
    ; it survived 16 iterations so we draw the solid green block.
    mov ax, 0ADBh
    jmp WRITE_VRAM

WRITE_VRAM:
    ; printing to the screen the char
    mov es:[di], ax     
    add di, 2           ; move forward 2 bytes in video memory

    ; moving to next colum
    add c_x, 3          
    dec col_cnt
    jz COL_DONE
    jmp COL_LOOP
COL_DONE:

    ; moving to next row
    add c_y, 6          
    dec row_cnt
    jz ROW_DONE
    jmp ROW_LOOP
ROW_DONE:

    jmp EXIT

DRAW_CELL:
    ; assigning the printed char based of iter value
    cmp iter, 3
    jle COL_1_3
    cmp iter, 7
    jle COL_4_7

    ; if it didnt jump, iter is 8-15
    mov ax, 0EDBh
    jmp WRITE_VRAM

COL_1_3:
    mov ax, 012Eh
    jmp WRITE_VRAM
COL_4_7:
    mov ax, 042Ah
    jmp WRITE_VRAM
    
EXIT:
    ; moving the command line to the bottom and exiting the program
    mov ah, 02h
    mov bh, 00h
    mov dh, 18h
    mov dl, 00h
    int 10h
    
    mov ah, 04Ch
    int 21h

END START

内容的提问来源于stack exchange,提问作者Nate3384

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.02 05:24:53