Hello!
Basic FPU Float32 Vector2D NASM Macros.
If i would like to build some OpenGL or other 2D, or even 3D program,
then, these macros would be quite useful, maybe for you too.
Vector2D structure: There are two 4x byte fields
struc VECTOR2D
VECTOR2D.X: resd 1
VECTOR2D.Y: resd 1
endstruc
These are basic Vector2D macros to manage FPU stack:
; ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
; vector2d (Basic)
; ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
; 1. vector2d.push 1
; 2. vector2d.pushv 2
; 3. vector2d.set 3
; 4. vector2d.pop 1
; 5. vector2d.pops 0
; [*],[*],[*],[*],[*],[*],[*],[*],[*],[*],[*],[*],[*],[*],[*],[*],[*],[*]
; [*],[*],[*],[*],[*],[*],[*],[*],[*],[*],[*],[*],[*],[*],[*],[*],[*],[*]
; [*],[*],[*],[*],[*],[*],[*],[*],[*],[*],[*],[*],[*],[*],[*],[*],[*],[*]
; ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
; vector2d (Basic)
; ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
struc VECTOR2D
VECTOR2D.X: resd 1
VECTOR2D.Y: resd 1
endstruc
; 1. vector2d.push:
; ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
%macro vector2d.push 1
float32.push %1
float32.push %1+4
%endmacro
; 2. vector2d.pushv:
; ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
%macro vector2d.pushv 2
sub esp,dword 8
mov dword [esp],__float32__(%1)
mov dword [esp+4],__float32__(%2)
vector2d.push esp
add esp,dword 8
%endmacro
; 3. vector2d.set:
; ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
%macro vector2d.set 3
mov dword [%1],__float32__(%2)
mov dword [%1+4],__float32__(%3)
%endmacro
; 4. vector2d.pop:
; ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
%macro vector2d.pop 1
float32.pop %1+4
float32.pop %1
%endmacro
; 5. vector2d.pops:
; ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
%macro vector2d.pops 0
sub esp,dword 8
float32.pop esp+4
float32.pop esp
%endmacro
These are Vector2D arithmetic macros:
; ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
; vector2d (Math)
; ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
; 1. vector2d.add 0-2
; 2. vector2d.addv 1-2
; 3. vector2d.sub 0-2
; 4. vector2d.subv 1-2
; 5. vector2d.mul 0-2
; 6. vector2d.mulv 1-2
; 7. vector2d.div 0-2
; 8. vector2d.divv 1-2
; [*],[*],[*],[*],[*],[*],[*],[*],[*],[*],[*],[*],[*],[*],[*],[*],[*],[*]
; [*],[*],[*],[*],[*],[*],[*],[*],[*],[*],[*],[*],[*],[*],[*],[*],[*],[*]
; [*],[*],[*],[*],[*],[*],[*],[*],[*],[*],[*],[*],[*],[*],[*],[*],[*],[*]
; ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
; vector2d (Math)
; ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
; 1. vector2d.add:
; ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
%macro vector2d.add 0-2
%if %0 > 0
%rep %0
vector2d.push %1
%rotate 1
%endrep
%endif
faddp st2,st0
faddp st2,st0
%endmacro
; 2. vector2d.addv:
; ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
%macro vector2d.addv 2-4
%if %0 = 3
%error Accepted 2x or 4x params (x0,y0 / x0,y0,x1,y1)
%endif
%rep %0 / 2
vector2d.pushv %1, %2
%rotate 2
%endrep
faddp st2,st0
faddp st2,st0
%endmacro
; 3. vector2d.sub:
; ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
%macro vector2d.sub 0-2
%if %0 > 0
%rep %0
vector2d.push %1
%rotate 1
%endrep
%endif
fsubp st2,st0
fsubp st2,st0
%endmacro
; 4. vector2d.subv:
; ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
%macro vector2d.subv 2-4
%if %0 = 3
%error Accepted 2x or 4x params (x0,y0 / x0,y0,x1,y1)
%endif
%rep %0 / 2
vector2d.pushv %1, %2
%rotate 2
%endrep
fsubp st2,st0
fsubp st2,st0
%endmacro
; 5. vector2d.mul:
; ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
%macro vector2d.mul 0-2
%if %0 > 0
%rep %0
vector2d.push %1
%rotate 1
%endrep
%endif
fmulp st2,st0
fmulp st2,st0
%endmacro
; 6. vector2d.mulv:
; ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
%macro vector2d.mulv 2-4
%if %0 = 3
%error Accepted 2x or 4x params (x0,y0 / x0,y0,x1,y1)
%endif
%rep %0 / 2
vector2d.pushv %1, %2
%rotate 2
%endrep
fmulp st2,st0
fmulp st2,st0
%endmacro
; 7. vector2d.div:
; ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
%macro vector2d.div 0-2
%if %0 > 0
%rep %0
vector2d.push %1
%rotate 1
%endrep
%endif
fdivp st2,st0
fdivp st2,st0
%endmacro
; 8. vector2d.divv:
; ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
%macro vector2d.divv 2-4
%if %0 = 3
%error Accepted 2x or 4x params (x0,y0 / x0,y0,x1,y1)
%endif
%rep %0 / 2
vector2d.pushv %1, %2
%rotate 2
%endrep
fdivp st2,st0
fdivp st2,st0
%endmacro
These are Vector2D macros:
; ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
; vector2d (Math)
; ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
; 9. vector2d.magnitude 0-1
; 10. vector2d.normalize 0-1
; 11. vector2d.normal 0-1
; 12. vector2d.dot 0-2
; [*],[*],[*],[*],[*],[*],[*],[*],[*],[*],[*],[*],[*],[*],[*],[*],[*],[*]
; [*],[*],[*],[*],[*],[*],[*],[*],[*],[*],[*],[*],[*],[*],[*],[*],[*],[*]
; [*],[*],[*],[*],[*],[*],[*],[*],[*],[*],[*],[*],[*],[*],[*],[*],[*],[*]
; ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
; vector2d (Math)
; ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
; 9. vector2d.magnitude:
; ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
%macro vector2d.magnitude 0-1
%if %0 = 1
vector2d.push %1
%endif
; Two times of "fld st1" is the same as vector2d.push %1
fld st1
fld st1
vector2d.mul
float32.add
fsqrt
%endmacro
; 10. vector2d.normalize:
; ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
%macro vector2d.normalize 0-1
%if %0 = 1
; One for the division
vector2d.push %1
%endif
; Second for the magnitude
fld st1
fld st1
vector2d.magnitude
; magnitude returned float, load second time
fld st0
vector2d.div
%endmacro
; 11. vector2d.normal:
; ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
%macro vector2d.normal 0-1
; For now, don't do auto normalize on incoming vector,
; let normalization for user.
; Disabled: vector2d.normalize %1
%if %0 = 1
vector2d.push %1
%endif
fchs
fxch st1
%endmacro
; 12. vector2d.dot:
; ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
%macro vector2d.dot 0-2
%if %0 > 0
%rep %0
vector2d.push %1
%rotate 1
%endrep
%endif
vector2d.mul
float32.add
%endmacro
Example code description:
Example code uses float32 macros.
Example code uses two output procedures.
Most of Vector2D macros are based on float32 macros.
For example, vector magnitude is a single float32, so, that's why we need a procedure to print that.
Procedure 1:
; ---------------------------------------------------------
; Procedure printfFloat32
; This procedure prints float32
; Param1: Index
; Param2: float32 Value
; ---------------------------------------------------------
Procedure 2:
; ---------------------------------------------------------
; Procedure printftVector2d
; This procedure prints Vector2d
; Param1: Index
; Param2: vector2d Value in stack: x, y
; ---------------------------------------------------------
Example code:
Demonstration of Vector2D macro usage, variations.
; ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
; vector2d
; ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
; 1. ------------------------------- (add)
vector2d.pushv 4.5,0.5
vector2d.pushv 3.0,2.0
vector2d.add
vector2d.pops
push dword 1
call printftVector2d
; 2. ------------------------------- (add)
vector2d.set vector1,4.5,0.5
vector2d.set vector2,3.1,2.1
vector2d.push vector1
vector2d.push vector2
vector2d.add
vector2d.pops
push dword 2
call printftVector2d
; 3. ------------------------------- (add)
vector2d.set vector1,4.5,0.5
vector2d.set vector2,3.2,2.2
vector2d.push vector1
vector2d.push vector2
vector2d.add
vector2d.pop vectorResult
push dword [vectorResult+4]
push dword [vectorResult+0]
push dword 3
call printftVector2d
; 4. ------------------------------- (add)
vector2d.set vector1,4.5,0.5
vector2d.set vector2,3.3,2.3
vector2d.add vector1,vector2
vector2d.pops
push dword 4
call printftVector2d
; 5. ------------------------------- (add)
vector2d.pushv 4.5,0.5
vector2d.addv 3.4,2.4
vector2d.pops
push dword 5
call printftVector2d
; 6. ------------------------------- (add)
vector2d.addv 4.5,0.5,3.5,2.5
vector2d.pops
push dword 6
call printftVector2d
; 7. ------------------------------- (div)
vector2d.pushv 30.0,40.0
vector2d.pushv 3.0,4.0
vector2d.div
vector2d.pops
push dword 7
call printftVector2d
; 8. ------------------------------- (divv)
vector2d.divv 33.0,44.0,3.0,4.0
vector2d.pops
push dword 8
call printftVector2d
; 9. ------------------------------- (sub)
vector2d.pushv 15.0,16.0
vector2d.pushv 3.0,4.0
vector2d.sub
vector2d.pops
push dword 9
call printftVector2d
; 10. ------------------------------- (subv)
vector2d.subv 16.0,17.0,3.0,4.0
vector2d.pops
push dword 10
call printftVector2d
; 11. ------------------------------- (mul)
vector2d.pushv 30.0,40.0
vector2d.pushv 3.0,4.0
vector2d.mul
vector2d.pops
push dword 11
call printftVector2d
; 12. ------------------------------- (mulv)
vector2d.mulv 31.0,41.0,3.0,4.0
vector2d.pops
push dword 12
call printftVector2d
; 13. ------------------------------- (magnitude)
vector2d.set vector1,5.0,4.0
vector2d.magnitude vector1
float32.pops
push dword 13
call printfFloat32
; 14. ------------------------------- (normalize)
vector2d.set vector1,5.0,4.0
vector2d.normalize vector1
vector2d.pops
push dword 14
call printftVector2d
; 15. ------------------------------- (normal)
vector2d.set vector1,5.0,4.0
vector2d.normal vector1
vector2d.pops
push dword 15
call printftVector2d
; 16. ------------------------------- (dot)
vector2d.set vector1,1.7,2.5
vector2d.set vector2,3.8,1.2
vector2d.dot vector1,vector2
float32.pops
push dword 16
call printfFloat32
Example code output:
1. vector2d: x: 7.500000, y:2.500000
2. vector2d: x: 7.600000, y:2.600000
3. vector2d: x: 7.700000, y:2.700000
4. vector2d: x: 7.800000, y:2.800000
5. vector2d: x: 7.900000, y:2.900000
6. vector2d: x: 8.000000, y:3.000000
7. vector2d: x: 10.000000, y:10.000000
8. vector2d: x: 11.000000, y:11.000000
9. vector2d: x: 12.000000, y:12.000000
10. vector2d: x: 13.000000, y:13.000000
11. vector2d: x: 90.000000, y:160.000000
12. vector2d: x: 93.000000, y:164.000000
13. float32: 6.403124
14. vector2d: x: 0.780869, y:0.624695
15. vector2d: x: -4.000000, y:5.000000
16. float32: 9.460000
Source files:
Added attachment:
1. Main compile file "fpu_float32_main.asm".
2. Included at compile time automatically: "fpu_float32_macros.asm".
3. Included at compile time automatically: "fpu_float32_vector2d_macros.asm".
Main compile file, also will contain, float32 macro examples too.
How to compile:
.Like this, in the way i did!
.NASM: "nasm.exe fpu_float32_main.asm -f win32 -o fpu_float32_main.o"
.GCC: "gcc fpu_float32_main.o -m32 -o fpu_float32_main.exe"
.That's it!
.Encryptor256.