circle.asm
· 3.0 KiB · NASM
Исходник
; boot2.asm
; nasm -f bin boot2.asm -o boot2.img
; qemu-system-i386 -drive format=raw,file=boot2.img
[org 0x7c00]
bits 16
start:
cli
xor ax, ax
mov ds, ax
mov es, ax
; --- 1) 切换到 320×200 256 色模式 (mode 13h) ---
mov ah, 0x00
mov al, 0x13
int 0x10
; --- 2) 清屏(黑色) ---
mov ax, 0xA000
mov es, ax
xor di, di
mov al, 0
mov cx, 320*200
rep stosb
; --- 3) 绘制灰色圆 ---
call draw_circle
jmp $
; -------------------------------------------------------
; draw_circle: 在 (160,100) 处以半径 80 画灰色圆
; -------------------------------------------------------
draw_circle:
mov cx, 80 ; radius = 80
xor dx, dx ; x = 0
mov bx, cx ; y = radius
mov ax, 1
sub ax, cx ; d = 1 - radius
circ_loop:
; 画出 8 个对称点
call plot_octants
; 更新决策变量 d
; temp = 4*x
mov si, dx
add si, si
add si, si
cmp ax, 0
jl d_negative
; d >= 0
mov di, bx
add di, di
add di, di ; di = 4*y
sub si, di ; si = 4*(x - y)
add si, 10
dec bx ; y--
jmp d_update
d_negative:
; d < 0
add si, 6
d_update:
add ax, si ; d += si
inc dx ; x++
cmp dx, bx
jle circ_loop
ret
; -------------------------------------------------------
; plot_octants: 将 (dx, bx) 对称的 8 点传入 plot_pixel
; 入口:DX=x, BX=y
; -------------------------------------------------------
plot_octants:
; 保存通用寄存
push ax
push bx
push cx
push dx
push si
push di
; ( x, y)
mov si, dx
mov di, bx
call plot_pixel
; ( y, x)
mov si, bx
mov di, dx
call plot_pixel
; (-x, y)
mov si, dx
neg si
mov di, bx
call plot_pixel
; (-y, x)
mov si, bx
neg si
mov di, dx
call plot_pixel
; (-x, -y)
mov si, dx
neg si
mov di, bx
neg di
call plot_pixel
; (-y, -x)
mov si, bx
neg si
mov di, dx
neg di
call plot_pixel
; ( x, -y)
mov si, dx
mov di, bx
neg di
call plot_pixel
; ( y, -x)
mov si, bx
mov di, dx
neg di
call plot_pixel
; 恢复寄存
pop di
pop si
pop dx
pop cx
pop bx
pop ax
ret
; -------------------------------------------------------
; plot_pixel:
; SI = x 偏移 (signed), DI = y 偏移 (signed)
; 在中心 (160,100) 上绘制一个灰色像素 (palette index = 7)
; -------------------------------------------------------
plot_pixel:
push ax
push bx
push cx
push dx
; 计算 px = 160 + SI, py = 100 + DI
mov ax, 160
add ax, si ; px
mov cx, 100
add cx, di ; py
; offset = py*320 + px = (py<<8)+(py<<6)+px
mov bx, cx
shl bx, 8
mov di, bx
mov bx, cx
shl bx, 6
add di, bx
add di, ax
mov al, 7 ; gray
mov [es:di], al
pop dx
pop cx
pop bx
pop ax
ret
times 510-($-$$) db 0
dw 0xAA55
1 | ; boot2.asm |
2 | ; nasm -f bin boot2.asm -o boot2.img |
3 | ; qemu-system-i386 -drive format=raw,file=boot2.img |
4 | |
5 | [org 0x7c00] |
6 | bits 16 |
7 | |
8 | start: |
9 | cli |
10 | xor ax, ax |
11 | mov ds, ax |
12 | mov es, ax |
13 | |
14 | ; --- 1) 切换到 320×200 256 色模式 (mode 13h) --- |
15 | mov ah, 0x00 |
16 | mov al, 0x13 |
17 | int 0x10 |
18 | |
19 | ; --- 2) 清屏(黑色) --- |
20 | mov ax, 0xA000 |
21 | mov es, ax |
22 | xor di, di |
23 | mov al, 0 |
24 | mov cx, 320*200 |
25 | rep stosb |
26 | |
27 | ; --- 3) 绘制灰色圆 --- |
28 | call draw_circle |
29 | |
30 | jmp $ |
31 | |
32 | ; ------------------------------------------------------- |
33 | ; draw_circle: 在 (160,100) 处以半径 80 画灰色圆 |
34 | ; ------------------------------------------------------- |
35 | draw_circle: |
36 | mov cx, 80 ; radius = 80 |
37 | xor dx, dx ; x = 0 |
38 | mov bx, cx ; y = radius |
39 | mov ax, 1 |
40 | sub ax, cx ; d = 1 - radius |
41 | |
42 | circ_loop: |
43 | ; 画出 8 个对称点 |
44 | call plot_octants |
45 | |
46 | ; 更新决策变量 d |
47 | ; temp = 4*x |
48 | mov si, dx |
49 | add si, si |
50 | add si, si |
51 | |
52 | cmp ax, 0 |
53 | jl d_negative |
54 | ; d >= 0 |
55 | mov di, bx |
56 | add di, di |
57 | add di, di ; di = 4*y |
58 | sub si, di ; si = 4*(x - y) |
59 | add si, 10 |
60 | dec bx ; y-- |
61 | jmp d_update |
62 | |
63 | d_negative: |
64 | ; d < 0 |
65 | add si, 6 |
66 | |
67 | d_update: |
68 | add ax, si ; d += si |
69 | inc dx ; x++ |
70 | cmp dx, bx |
71 | jle circ_loop |
72 | ret |
73 | |
74 | ; ------------------------------------------------------- |
75 | ; plot_octants: 将 (dx, bx) 对称的 8 点传入 plot_pixel |
76 | ; 入口:DX=x, BX=y |
77 | ; ------------------------------------------------------- |
78 | plot_octants: |
79 | ; 保存通用寄存 |
80 | push ax |
81 | push bx |
82 | push cx |
83 | push dx |
84 | push si |
85 | push di |
86 | |
87 | ; ( x, y) |
88 | mov si, dx |
89 | mov di, bx |
90 | call plot_pixel |
91 | |
92 | ; ( y, x) |
93 | mov si, bx |
94 | mov di, dx |
95 | call plot_pixel |
96 | |
97 | ; (-x, y) |
98 | mov si, dx |
99 | neg si |
100 | mov di, bx |
101 | call plot_pixel |
102 | |
103 | ; (-y, x) |
104 | mov si, bx |
105 | neg si |
106 | mov di, dx |
107 | call plot_pixel |
108 | |
109 | ; (-x, -y) |
110 | mov si, dx |
111 | neg si |
112 | mov di, bx |
113 | neg di |
114 | call plot_pixel |
115 | |
116 | ; (-y, -x) |
117 | mov si, bx |
118 | neg si |
119 | mov di, dx |
120 | neg di |
121 | call plot_pixel |
122 | |
123 | ; ( x, -y) |
124 | mov si, dx |
125 | mov di, bx |
126 | neg di |
127 | call plot_pixel |
128 | |
129 | ; ( y, -x) |
130 | mov si, bx |
131 | mov di, dx |
132 | neg di |
133 | call plot_pixel |
134 | |
135 | ; 恢复寄存 |
136 | pop di |
137 | pop si |
138 | pop dx |
139 | pop cx |
140 | pop bx |
141 | pop ax |
142 | ret |
143 | |
144 | ; ------------------------------------------------------- |
145 | ; plot_pixel: |
146 | ; SI = x 偏移 (signed), DI = y 偏移 (signed) |
147 | ; 在中心 (160,100) 上绘制一个灰色像素 (palette index = 7) |
148 | ; ------------------------------------------------------- |
149 | plot_pixel: |
150 | push ax |
151 | push bx |
152 | push cx |
153 | push dx |
154 | |
155 | ; 计算 px = 160 + SI, py = 100 + DI |
156 | mov ax, 160 |
157 | add ax, si ; px |
158 | mov cx, 100 |
159 | add cx, di ; py |
160 | |
161 | ; offset = py*320 + px = (py<<8)+(py<<6)+px |
162 | mov bx, cx |
163 | shl bx, 8 |
164 | mov di, bx |
165 | mov bx, cx |
166 | shl bx, 6 |
167 | add di, bx |
168 | add di, ax |
169 | |
170 | mov al, 7 ; gray |
171 | mov [es:di], al |
172 | |
173 | pop dx |
174 | pop cx |
175 | pop bx |
176 | pop ax |
177 | ret |
178 | |
179 | times 510-($-$$) db 0 |
180 | dw 0xAA55 |
181 | |
182 |