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_xy_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
- 1-3次迭代逃逸:输出
教师提供了预期效果图,但我编写的代码生成的图形与示例存在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
相关产品推荐
相关产品推荐

