News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Preassembly tasks/operations

Started by RedXVII, February 13, 2006, 05:12:32 PM

Previous topic - Next topic

RedXVII

Is there anyway to do manipulations to number before assembly:

for example:

i believe its possible to do something like
.invoke myfunction, 5*3

1) Is it possible to do larger and more complicated arithmetic operations before assembly?
eg.

5*4+3*21h-3

2) Is it possible to do run my assembly operations before assembly?
eg.

calculatebinarypattern macro number
  mov eax, number                            ;I dont want this bit to assemble
  shr eax, 2                                      ;I want it just to replace my number with the binary pattern directly
  blah blah blah..


The idea is i want to just do something like

.invoke Myfunction, calculatebinarypattern(234)

i dont want to have calculatebinarypattern every time i do this; i just want it replaced with the return vaue at the end. Its my obssession with making code run fast  :bg


Cheers  :U

arafel

MASM allows usage of some logical operators (and, or, xor, shl, shr, not. if iam not mistaken) and supports complex operations as well, so you could do something like:


calculatebinarypattern MACRO number:REQ

EXITM <(5*4+3*21h-number) SHR 2>  ; value in brackets is calculated and then shr-ed by two. this's just an example...

ENDM

invoke Myfunction, calculatebinarypattern(234)

RedXVII

SWEETT! Does that really work!?

I cant believe it - im gonna have to go try it now, thats like, so cool  :bg

RedXVII

Unfortunately, my calculation is a bit longer than just that, a couple of lines of it;

1) Can you use multiple lines?
2) Does it accept .if decisions?


Thanks  :U

zooba

Of course you can. MASM's macro component is extremely powerful (second only to HLA I believe). If you have access to all the values at compile-time there is no problem:

calc MACRO num1, num2
    LOCAL tmp1, tmp2
    tmp1 = num1 * 2
    IF tmp1 GE num2
        EXITM <num2>
    ENDIF
    EXITM <num1>
ENDM

RedXVII

wow, this is mega cool  :bg and really really.... powerful  :bdg

More questions though  :toothy

1) Does it accept floats as a parameters perform floating point calculations on them and can it return floats?
2) Do i have to say what type of variable in the macro LOCAL variable is?

Thanks for your patience and time - this should be the last few questions

cheers  :U

zooba

No, no, no problem and no :wink

That is:

No, it doesn't work with floating point numbers.

No, you don't have to say what type of variable a local is - it is MASM's internal variant type (LOCAL just creates an alias for an autogenerated name, otherwise these variables have global scope :U)

No problem re: patience and time :bg

And no. This won't be your last few questions, cos there's so so so so so much in there - there's very few people who have finished all their questions :wink :U :8)
Don't worry. There's always people here to answer them :thumbu

Cheers,

Zooba

RedXVII

crap, i honestly thaught that one was the last. But damn zooba, youre right like 99.9% of the time.

This time, it concerns divisions in macros.

if i do

calc MACRO num1, num2
  LOCAL endnum
  endnum=num1/num2
  EXITM <endnum>
ENDM


Im worried ill lose the deicamal point (the all important decimal point after the division).
eg.

calc(5 , 2)
returns ?

Ok, this isnt really important in the above example, but it is in my huge momma macro  :toothy

1) does it round up/down or always up/down?
2) can i use the % operator to save the day?
3) can i make the assembler geterate a custom error if a certain condition is met?

Cheers  :U

zooba

calc(5,2) returns 2
5 MOD 2 returns 1 :wink

The % operator has a special meaning which is really hard to explain and most of the time I just trial and error until it works. It is supposed to evaluate as much as it can on the line that follows, rather than interpreting it as plain text.

For example:
x TEXTEQU <hello>
ECHO x
%ECHO x

displays on compilation
x
hello


Which I think should answer your third question, the ECHO command displays text while the program is being compiled. There is also an '.ERR' directive (and .ERRB/NB/DEF/NDEF/DIF/IDN/DIFI/IDNI) which causes a fatal error, but not until the rest of the code has been compiled. I prefer my own ECHO statement - it looks neater :U You can use @FileName, @FileCur and @Line to display information about the file, but they will require a '%' at the start of the line.

If you're using Quick Editor, go to the Help menu and choose MASM32 Help for heaps more information about all of these. Otherwise it's MASM32.HLP in the Help folder :U

Cheers,

Zooba

RedXVII

This is working a treat so far mate.

One more request however, because i want to tidy this up a bit.

Is it possible to detect how many digits were passed into the macro, 0 is causeing a problem here, for example.

mymacro MACRO number
  LOCAL numberofdigits
  ...                           ;insert code here
  exitm <numberofdigits>
endm


so that
mymacro(12345) returns 5
mymacro(045) returns 3
mymacro(0012) returns 4

Thanks zooba, i estimate youve saved me about 16 hours of non stop websearching, 8 hours of maniac depression and 6 hours of beating up a cushions. :bg

Cheers  :U

zooba

Easy :bg

The parameter is passed as a string until you try and treat it as a number. MASM provides some nifty string functions:

SIZESTR, SUBSTR, INSTR and CATSTR. Look up the MASM32 help file I mentioned for full explanations, but to do what you want:

mymacro MACRO number
    LOCAL numberofdigits
    numberofdigits SIZESTR <number>
    EXITM <numberofdigits>
ENDM


Cheers, :U

RedXVII

Alright, things have gone pear shaped, my MACRO is screwing up and i dont know where. It goes into an infinate loop.  :'(

How do i print what value of my variables are during assembly?

ECHO isnt working right for me, whats the correct syntax?

MichaelW

See masm32\macros\macros.asm for the definition of num2str.

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    include \masm32\include\masm32rt.inc

    testit MACRO
      junk TEXTEQU <my other brother darryl>
      % echo junk
      n = 101     
      % echo num2str(n)
    ENDM
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    .data
    .code
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
start:
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    testit
    inkey "Press any key to exit..."
    exit
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end start
eschew obfuscation

zooba

My preferred way of display values is to use @CatStr:

%echo @CatStr(%n)

That way it's easy to put extra stuff in:

%echo @CatStr(<n = >, %n)
Note: the angle braces mean that everything inside them is a single parameter - all they really do in this case is preserve the trailing space :wink