Author Topic: Assembly language help  (Read 2248 times)

0 Members and 3 Guests are viewing this topic.

MseTrap

  • Guest
Assembly language help
« on: February 02, 2014, 11:11:54 PM »
I know this is probably not the right place to ask, but I know these forums are full of smart folks who know more x86 asm than I do. 
I've written a little toy parser that takes basic style expressions and compiles them to assembly and was curious if someone would be kind enough let me know if the generated asm looks correct.

Any help or comments would be appreciated.
Thanks!

This as input:
Code: [Select]
var a;
var b;
var othervar;
a=1+2-3*4/5;
b=a*(a+-a)*-0.1;
if (a>b) then
othervar=a;
else
othervar=b;
endif

Will produce this output.
Code: [Select]
;------Begin------;
_func:
push ebp
mov ebp,esp
sub esp, 12
fld dword [_0]
fld dword [_1]
faddp
fld dword [_2]
fld dword [_3]
fmulp
fld dword [_4]
fdivp
fsubp
fstp dword [ebp-4] ;store in a
fld dword [ebp-4] ;load 'a'
fld dword [ebp-4] ;load 'a'
fld dword [ebp-4] ;load 'a'
fchs
faddp
fmulp
fld dword [_5]
fmulp
fstp dword [ebp-8] ;store in b
fld dword [ebp-4] ;load 'a'
fld dword [ebp-8] ;load 'b'
fxch
fucompp
fnstsw ax
sahf
setbe al
movzx eax,al
cmp eax,0
jne _else2:
fld dword [ebp-4] ;load 'a'
fstp dword [ebp-12] ;store in othervar
jmp _endif1:
_else2:
fld dword [ebp-8] ;load 'b'
fstp dword [ebp-12] ;store in othervar
jmp _endif1:
_endif1:
mov esp,ebp
pop ebp
ret
;------End------;

section "data"
_0:
dd 0x3F800000 ;-> 1.00000000
align 4
_1:
dd 0x40000000 ;-> 2.00000000
align 4
_2:
dd 0x40400000 ;-> 3.00000000
align 4
_3:
dd 0x40800000 ;-> 4.00000000
align 4
_4:
dd 0x40A00000 ;-> 5.00000000
align 4
_5:
dd 0xBDCCCCCD ;-> -0.100000001
align 4


Charles Pegge

  • Guest
Re: Assembly language help
« Reply #1 on: February 03, 2014, 03:45:56 AM »
Had a very brief look.

You could take advantage of the fcomi / fucomi instructions which set the CPU condition flags directly.

You will need to use ja / jb type jumps instead of jg / jl

Example:
Code: [Select]
fld1         ; 1.0

 fld1
 fadd st(0)   ; 2.0

 fcomip st(1) ; compare 2-1
 fstp st(0)   ; flush last term
 jna nnn      ; jump not above
 print "ok"
 nnn:
« Last Edit: February 03, 2014, 03:57:39 AM by Charles Pegge »

MseTrap

  • Guest
Re: Assembly language help
« Reply #2 on: February 03, 2014, 08:07:18 AM »
Thanks Charles!
I'll look into making the change.

When oxygen compiles fpu statements, do you keep a virtual count of the fpu stack depth to prevent losing items?
Thanks

Charles Pegge

  • Guest
Re: Assembly language help
« Reply #3 on: February 03, 2014, 09:09:51 AM »
No, but I don't use FPU assembly code very often, and then keep the FPU stacking no more than 4 deep. Stack memory is usually held in the cache, with very fast access, so there is no great disadvantage in saving intermediate values to temp variables, to avoid complex maneuvers inside the FPU.

MseTrap

  • Guest
Re: Assembly language help
« Reply #4 on: February 03, 2014, 11:39:45 AM »
Thanks!
I implemented a stack shadow function in the parser.
Does this look reasonable as a way of preserving the proper calculations?
Code: [Select]
var a;
a=(1+(2+(3+(4+(5+(6+(7+(8-9))))))));

;------Begin------;
_func:
push ebp
mov ebp,esp
finit
sub esp, 4
fld dword [_0]
fld dword [_1]
fld dword [_2]
fld dword [_3]
fld dword [_4]
fld dword [_5]
;overflow to stack
sub esp, 4
fld st(7)
fstp dword [ebp-8]
fld dword [_6]
;overflow to stack
sub esp, 4
fld st(7)
fstp dword [ebp-12]
fld dword [_7]
;overflow to stack
sub esp, 4
fld st(7)
fstp dword [ebp-16]
fld dword [_8]
fsubp
;restor from stack
fld dword [ebp-16]
fstp st(7)
add ebp, 4
faddp
;restor from stack
fld dword [ebp-12]
fstp st(7)
add ebp, 4
faddp
faddp
faddp
faddp
faddp
faddp
fstp dword [ebp-4] ;store in a

mov esp,ebp
pop ebp
ret
;------End------;

section "data"
_0:
dd 0x3F800000 ;-> 1.00000000
align 4
_1:
dd 0x40000000 ;-> 2.00000000
align 4
_2:
dd 0x40400000 ;-> 3.00000000
align 4
_3:
dd 0x40800000 ;-> 4.00000000
align 4
_4:
dd 0x40A00000 ;-> 5.00000000
align 4
_5:
dd 0x40C00000 ;-> 6.00000000
align 4
_6:
dd 0x40E00000 ;-> 7.00000000
align 4
_7:
dd 0x41000000 ;-> 8.00000000
align 4
_8:
dd 0x41100000 ;-> 9.00000000
align 4

Also, Does Oxygen have any built-in functionality for inspecting the fpu at runtime?



Thanks again!
« Last Edit: February 03, 2014, 12:14:03 PM by MseTrap »

Charles Pegge

  • Guest
Re: Assembly language help
« Reply #5 on: February 03, 2014, 03:34:45 PM »
There is no advantage in preloading values onto the fpu stack when you can operate directly from variables. It is only needed when nesting due to operator-precedence. To avoid deep nestings, Oxygen breaks expressions down and stores intermediate values to temporary local variables.

There is an example of code for viewing registers. which could be used at run-time:

/examples/Diagnostics/RegSnapShot.o2bas

but there is nothing more versatile for diagnostics, than a well placed print statement :)


MseTrap

  • Guest
Re: Assembly language help
« Reply #6 on: February 03, 2014, 11:14:07 PM »
Thanks Charles,
That makes a lot of sense, and would save quite a few instructions. I'm mostly concerned with the correctness of the generated assembly at this point. the parser spits out assembly as it moves along, so there are not many optimizations i can do without building a syntax tree. I've little experience with assembly programming too.
Thanks for the help!