flat assembler
Message board for the users of flat assembler.

Index > Macroinstructions > Calc macro

Author
Thread Post new topic Reply to topic
VitalOne



Joined: 29 Jul 2003
Posts: 54
Location: USA
VitalOne
Here's a calc macro I made that calculates using binary operations and returns the value in eax. It allows you do things like calc [var],"*",[var2],"+",6

Code:
macro calc arg,[args]
{
common
mov eax,arg
local flag
flag = -1
forward
if args eqtype ""
   if args='+'
        flag=0
   else if args='-'
        flag=1
   else if args='*'
        flag=2
   else if args='/'
        flag=3
   end if
else
   if flag=0    ;Addition
        add eax,args
   else if flag=1 ;Subtraction
        sub eax,args
   else if flag=2 ;Multiplication
        mov ecx,args
        mul ecx
   else if flag=3 ;Division
        xor edx,edx
        mov ecx,args
        div ecx
   end if
end if
}
    


So you could do something like calc [var],'/',3,'+',[var2] (32-bit for now) . The only problem I have is that it doesn't follow the order of operations (PEMDAS). Is there anyway to make it follow the order?
Post 04 Jan 2004, 02:25
View user's profile Send private message AIM Address Yahoo Messenger Reply with quote
scientica
Retired moderator


Joined: 16 Jun 2003
Posts: 689
Location: Linköping, Sweden
scientica
[edit]
/me bashes head against wall, what was I thinking - untested code was wroly (re)written by me.

Code:
;-tested- (and works)
macro calc arg,[operation, variable]
{
common
 mov eax,arg
forward
 if operation eqtype "" ; basic error check
    if operation='+'
         add eax, variable
    else if operation='-'
         sub eax, variable
    else if operation='*'
         mov ecx, variable
         mul ecx
    else if operation='/'
         xor edx, edx
         mov ecx, variable
         div ecx
    else
         display "Invalid operation, must be either '+', '-', '*' or '/'",10 ; 10,13 in windows/DOS
         display "operation = ", operation, 10
    end if
 end if
}

macro calc2 arg, [op, variable] {
common
 mov eax,arg
forward
    if 1 op 1 eq 1+1
         add eax, variable
    else if 1 op 1 eq 1-1
         sub eax, variable
    else if 1 op 1 eq 1*1
         mov ecx, variable
         mul ecx
    else if 1 op 1 eq 1/1
         xor edx, edx
         mov ecx, variable
         div ecx
    else
         display "Invalid operation, must be either +, -, * or /",10 ; 10,13 in windows/DOS
    end if
}
   
virtual at 0
var:    
 dd 0
var2:  
end virtual

;;; db '--------------------------------------------------------------------------------',10
calc [var],'/',3,'+',[var2]
dd 90909090h
;;; db 10,'--------------------------------------------------------------------------------',10
calc2 [var], /, 3, +, [var2]
;;; db 10,'--------------------------------------------------------------------------------',10    


gives this output when running the compiled file thru ndisasm:
Code:
[frekla@ns1 tmp]$ fasm test.asm test.txt && /usr/bin/ndisasm test.txt 
flat assembler  version 1.50
1 passes, 46 bytes.
00000000  66A10000          mov eax,[0x0]
00000004  6631D2            xor edx,edx
00000007  66B903000000      mov ecx,0x3
0000000D  66F7F1            div ecx
00000010  6603060400        add eax,[0x4]
00000015  90                nop
00000016  90                nop
00000017  90                nop
00000018  90                nop
00000019  66A10000          mov eax,[0x0]
0000001D  6631D2            xor edx,edx
00000020  66B903000000      mov ecx,0x3
00000026  66F7F1            div ecx
00000029  6603060400        add eax,[0x4]
[frekla@ns1 tmp]$     

[/edit]

_________________
... a professor saying: "use this proprietary software to learn computer science" is the same as English professor handing you a copy of Shakespeare and saying: "use this book to learn Shakespeare without opening the book itself.
- Bradley Kuhn
Post 04 Jan 2004, 12:39
View user's profile Send private message Visit poster's website Reply with quote
scientica
Retired moderator


Joined: 16 Jun 2003
Posts: 689
Location: Linköping, Sweden
scientica
Perhaps I should explain the code above:
bot macros operates like this, get argument, do operation with next argument, get operation, do operation on result of previous operation - just like old calculators Smile
the calc macro takes arguments in the form:
calc first_term, '{operation}', second_term, ...( '{operation}', n_term)
the calc2 does tha same but does not use quoted argurments (thus you use + instead of '+' ), couldn't get it to wok with eqtype so it ended up two macros :/

_________________
... a professor saying: "use this proprietary software to learn computer science" is the same as English professor handing you a copy of Shakespeare and saying: "use this book to learn Shakespeare without opening the book itself.
- Bradley Kuhn
Post 04 Jan 2004, 13:22
View user's profile Send private message Visit poster's website Reply with quote
Tommy



Joined: 17 Jun 2003
Posts: 492
Location: Norway
Tommy
Hi Scientica!

I modified your macro a little bit so that the output will be more optimized... Wink
Code:
use32

MAX_X = 32

macro pow2 val {
  x = 0
  z = 1
  result = 1
  repeat MAX_X
    result = result * 2
    if result = val
      x = z
    end if
    z = z + 1
  end repeat
}

macro assign reg,val {
  if val eqtype 0
    if val < 256
      xor e#reg#x,e#reg#x
      mov reg#l,val
    else
      mov e#reg#x,val
    end if
  else
    mov e#reg#x,val
  end if
}

macro multiply val {
  if val eqtype 0
    if val > 1
      pow2 val
      if x > 0
        shl eax,x
      else
        assign c,val
        mul ecx
      end if
    end if
  else
    assign c,val
    mul ecx
  end if
}

macro divide val {
  if val eqtype 0
    if val > 1
      pow2 val
      if x > 0
        shr eax,x
      else
        xor edx,edx
        assign c,val
        div ecx
      end if
    end if
  else
    xor edx,edx
    assign c,val
    div ecx
  end if
}

macro calc arg,[op,argn] {
  common
    assign a,arg
  forward
    if 1 op 1 eq 1+1
      if argn eq 1
        inc eax
      else
        add eax,argn
      end if
    else if 1 op 1 eq 1-1
      if argn eq 1
        dec eax
      else
        sub eax,argn
      end if
    else if 1 op 1 eq 1*1
      multiply argn
    else if 1 op 1 eq 1/1
      divide argn
    else
      display "Invalid operation",13,10
    end if
}

calc 15,+,45,/,6,*,32    
Outputs:
Code:
00000000  31C0              xor eax,eax
00000002  B00F              mov al,0xf
00000004  83C02D            add eax,byte +0x2d
00000007  31D2              xor edx,edx
00000009  31C9              xor ecx,ecx
0000000B  B106              mov cl,0x6
0000000D  F7F1              div ecx
0000000F  C1E005            shl eax,0x5    

Regards,
Tommy
Post 04 Jan 2004, 19:22
View user's profile Send private message Visit poster's website Reply with quote
VitalOne



Joined: 29 Jul 2003
Posts: 54
Location: USA
VitalOne
Thanks guys, except it still doesn't follow the order of operations. I'm a bit confused...does anyone have any idea on how to get it follow the order of operations?

Thanks for improving my macro anyway.
Post 05 Jan 2004, 02:11
View user's profile Send private message AIM Address Yahoo Messenger Reply with quote
scientica
Retired moderator


Joined: 16 Jun 2003
Posts: 689
Location: Linköping, Sweden
scientica
You mean like div and multiply goes before plus and minus? I'ts possible to solve, by adding support for paranthesis (and angle brackets ("<>")) - I think that requires a good nights sleep, but it's "do-able" I think.

_________________
... a professor saying: "use this proprietary software to learn computer science" is the same as English professor handing you a copy of Shakespeare and saying: "use this book to learn Shakespeare without opening the book itself.
- Bradley Kuhn
Post 05 Jan 2004, 02:33
View user's profile Send private message Visit poster's website Reply with quote
VitalOne



Joined: 29 Jul 2003
Posts: 54
Location: USA
VitalOne
But it would have to push the calculation in the <> to the stack, then some how at the end find out the order where it was, then calculate...how?
Post 09 Jan 2004, 06:56
View user's profile Send private message AIM Address Yahoo Messenger Reply with quote
scientica
Retired moderator


Joined: 16 Jun 2003
Posts: 689
Location: Linköping, Sweden
scientica
I thougt of something like:
Code:
calc 15,+,45,/, (, <6,+,5,> ),*,32    

which would first do 15+45, and then recurse (call it self with 6,+,5 as argument ), and then divide, and finally multiply by 32.

_________________
... a professor saying: "use this proprietary software to learn computer science" is the same as English professor handing you a copy of Shakespeare and saying: "use this book to learn Shakespeare without opening the book itself.
- Bradley Kuhn
Post 09 Jan 2004, 23:49
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar
Assembly Artist


Joined: 16 Jun 2003
Posts: 7422
Location: Kraków, Poland
Tomasz Grysztar
You can use the "equ" and "restore" combination to do a kind of stack operations on symbolic constants.
Post 10 Jan 2004, 01:11
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2019, Tomasz Grysztar.

Powered by rwasa.