.section .rodata
.set width, 1920
.set height, 1200
header:
.byte 0 /* id_length */
.byte 0 /* color_map_type */
.byte 2 /* image_type */
.word 0 /* first_entry_index */
.word 0 /* color_map_length */
.byte 0 /* color_map_entry_size */
.word 0 /* x_origin */
.word height /* y_origin */
.word width /* image_width */
.word height /* image_height */
.byte 24 /* pixel_depth */
.byte 32 /* image_descriptor */
.set headerlen, . - header
.section .bss
.set pixels, width * height
.lcomm buf, 3 * pixels
.set buflen, 3 * pixels
.section .text
mandelbrot:
push %rbx
/*
* xmm0 c real
* xmm1 c imag
* xmm2 tmp1/z real
* xmm3 tmp2/z imag
* xmm4 max
* xmm5 r/abs/Z real
* xmm6 i/Z imag
* xmm7 Ztemp
*/
/* a = -2.5 + 3.5 * x / w */
/* a = x */
cvtsi2ss %rax, %xmm0
/* a /= w */
mov $width, %rax
cvtsi2ss %rax, %xmm7
divss %xmm7, %xmm0
/* a *= 35 */
mov $35, %rax
cvtsi2ss %rax, %xmm7
mulss %xmm7, %xmm0
/* a /= 10 */
mov $10, %rax
cvtsi2ss %rax, %xmm7
divss %xmm7, %xmm0
/* a -= 2.5 */
mov $25, %rax
cvtsi2ss %rax, %xmm2
divss %xmm7, %xmm2
subss %xmm2, %xmm0
/* b = 1 - 2. * y / h */
/* b = y */
cvtsi2ss %rdi, %xmm1
/* b /= h */
mov $height, %rax
cvtsi2ss %rax, %xmm7
divss %xmm7, %xmm1
/* b *= 2. */
mov $2, %rax
cvtsi2ss %rax, %xmm7
mulss %xmm7, %xmm1
/* b = 1 - b */
movss %xmm1, %xmm7
mov $1, %rax
cvtsi2ss %rax, %xmm1
subss %xmm7, %xmm1
/* c = a + b * i */
/* z = c */
movss %xmm0, %xmm2
movss %xmm1, %xmm3
/* max = 100 */
mov $100, %rax
cvtsi2ss %rax, %xmm4
/* loop at most 256 times */
mov $256, %rcx
mandelloop:
/* abs = cabs(z) */
movss %xmm2, %xmm5
movss %xmm3, %xmm6
mulss %xmm5, %xmm5
mulss %xmm6, %xmm6
addss %xmm6, %xmm5
sqrtss %xmm5, %xmm5
/* if(cabs(z) > max) goto mandelend */
cmpltss %xmm4, %xmm5
cvtss2si %xmm5, %rax
cmp $0, %rax
je mandelend
/* z = z * z + c */
movss %xmm2, %xmm5
movss %xmm3, %xmm7
mulss %xmm5, %xmm5
mulss %xmm7, %xmm7
/* A = aa - bb */
subss %xmm7, %xmm5
/* B = ab */
mulss %xmm2, %xmm3
/* B *= 2 */
addss %xmm3, %xmm3
movss %xmm5, %xmm2
/* Z += c */
addss %xmm0, %xmm2
addss %xmm1, %xmm3
loop mandelloop
mandelend:
mov %rcx, %rax
pop %rbx
ret
.globl _start
_start:
/* write header */
mov $1, %rax /* sys_write */
mov $1, %rdi /* stdout */
mov $header, %rsi
mov $headerlen, %rdx
syscall
/* render image */
mov $buf, %rbx
mov $0, %rdi
lineloop:
mov $width, %rcx
mov $0, %rax
pixelloop:
mov $width, %rax
sub %rcx, %rax
push %rcx
call mandelbrot
pop %rcx
movb %al, (%rbx)
inc %rbx
movb %al, (%rbx)
inc %rbx
movb %al, (%rbx)
inc %rbx
loop pixelloop
inc %rdi
cmp $height, %rdi
jl lineloop
/* write image */
mov $1, %rax /* sys_write */
mov $1, %rdi /* stdout */
mov $buf, %rsi
mov $buflen, %rdx
syscall
/* exit */
mov $60, %rax /* sys_exit */
mov $0, %rdi
syscall