Author Topic: Macro question  (Read 11346 times)

Offline Mich

  • Jr. Member
  • *
  • Posts: 8
Macro question
« on: May 02, 2013, 12:59:09 AM »
I have the following macro:
Code: [Select]
%macro writeLn 1-*
%rep %0
%ifstr %1
%warning %1 string
%endif
%ifnum %1
%warning %1 number
%endif
%ifid %1
%ifidni %1,edx
%warning %1 reg
%elifidni %1,eax
%warning %1 reg
%else
%warning %1 addr
%endif
%endif
%ifidni %1,[eax]
%warning %1 reg pointer
%endif
%rotate 1
%endrep
%warning call to stdout
%endm

\nasm\bin\nasm -f win32 "\writeLn.asm"
warning: (writeLn:17) "number: " string
warning: (writeLn:17) 3 number
warning: (writeLn:17) NewLine addr
warning: (writeLn:17) infile addr
warning: (writeLn:17) NewLine addr
warning: (writeLn:17) edx reg
warning: (writeLn:17) eax reg
warning: (writeLn:19) call to print routine
warning: (writeLn:20) [eax] reg pointer

Make done.
This works for each %ifidni %1,[reg]. Not much of a problem for only 8 registers
writeLn "string [eax]",[eax],NewLine   ; this works

writeLn "memory @  [anyVar]",[anyVar]   ;this does not work, no %ifidni

What I'm looking for is a way to test between:
[anyVar]
anyVar in my macro
%ifidni %1,edx or eax or ctc

Your help and suggestions are welcome
Klod

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Macro question
« Reply #1 on: May 03, 2013, 11:20:06 PM »
Hi Klod - welcome back under your new name (I suspect this indicates a problem with the Forum). I'm not a vey sophisticated macro user. I'm not sure I understand the problem. You need to distinguish between "anyvar" and "[anyvar]"? Would you do something different with them?

There's a way to extract a substring (I'd have to look it up). You might be able to do that, and check for a '['... if that's what you need to do...

I'm sorry I can't be more help... maybe somebody else will have some suggestion.

Best,
Frank


Offline Bryant Keller

  • Forum Moderator
  • Full Member
  • *****
  • Posts: 360
  • Country: us
    • About Bryant Keller
Re: Macro question
« Reply #2 on: May 08, 2013, 03:39:12 PM »
Hi Mich,

I threw this quick example together so let me know if there are any problems. I hope this gets you going in the right direction.

Code: [Select]
%macro writeLn 1-*
%rep %0
%ifstr %1
%warning %1 string
%elifnum %1
%warning %1 number
%else
%push
%defstr %$id %1
%strlen %$idlen %$id
%substr %$first_char %$id 1
%substr %$last_char %$id %$idlen

%ifidni %$first_char,'['
%ifidni %$last_char,']'
%warning %$id pointer
%else
%warning invalid pointer
%endif
%else
%if %$idlen = 3
%substr %$reg %$id 2,3
%elif %$idlen = 2
%define %$reg %1
%else
%define %$reg
%endif

%ifidni %$reg,'ax'
%warning %1 register
%elifidni %$reg,'bx'
%warning %1 register
%elifidni %$reg,'cx'
%warning %1 register
%elifidni %$reg,'dx'
%warning %1 register
%elifidni %$reg,'si'
%warning %1 register
%elifidni %$reg,'di'
%warning %1 register
%elifidni %$reg,'sp'
%warning %1 register
%elifidni %$reg,'bp'
%warning %1 register
%elifidni %$reg,'al'
%warning %1 register
%elifidni %$reg,'bl'
%warning %1 register
%elifidni %$reg,'cl'
%warning %1 register
%elifidni %$reg,'dl'
%warning %1 register
%elifidni %$reg,'ah'
%warning %1 register
%elifidni %$reg,'bh'
%warning %1 register
%elifidni %$reg,'ch'
%warning %1 register
%elifidni %$reg,'dh'
%warning %1 register
%elifidni %$reg,'cs'
%warning %1 segment register
%elifidni %$reg,'ds'
%warning %1 segment register
%elifidni %$reg,'es'
%warning %1 segment register
%elifidni %$reg,'gs'
%warning %1 segment register
%elifidni %$reg,'fs'
%warning %1 segment register
%elifidni %$reg,'ss'
%warning %1 segment register
%else
%warning %1 address
%endif
%endif
%pop
%endif
%rotate 1
%endrep
%endmacro

writeLn 1, "hello", eax, [ebx]

Regards,
Bryant Keller

About Bryant Keller
bkeller@about.me

Offline Mich

  • Jr. Member
  • *
  • Posts: 8
Re: Macro question
« Reply #3 on: May 10, 2013, 12:22:10 AM »
Hi Frank,
yes I did have problems with the boards. One day I tried to log on and got a message that my IP address has been flagged as spamer site. There was a link to a website and the address I was logged on was listed, one of about 60 Telus IP addresses. It was also suggested that I may have a virus and so I did a manual deep cycle virus scan. No viruses on my machine. The next time I logged on I got the goofy, now standard procedure questionnaire. I thought what the..... and left. Next time around I could not even get on the message board, I was immediately redirected. I tried to log on from work and to my surprise my password did not work anymore. I tried the forgot password routine and was informed the user name does not exist. Just for fun I tried to set up an account with my old user name and was informed that this user name was taken!! Funny, I got banned from winasm community forum, Masm forum and Nasm forum all at the same time. I had been a member for 10 years. Could not find a way to appeal the boards decision so here I am. I have to warn you, since I'm logged in as an alias, I'm not quite myself.

I followed your advise, and came up with this. It is not all I was looking for but it will do fine for now. I am playing around with all sorts of ideas right now and I print results to the console constantly. I have been using printf so far but I need to constantly change the format strings depending on what I want to print out.
Eg, printf ā€œ%sā€ ,edx  for a string
      printf ā€œ%0Xā€ ,edx , for numbers

It is a very crude way of doing it but works for the stuff I do at present.

Code: [Select]
%macro writeLn 1-*
%push
%rep %0
%ifstr %1
pusha
sc lstrcat,outbuf, %1
%warning %1 string
popa
%elifnum %1
pusha
sc wsprintfA,szNUM,"%d ",%1
sc lstrcat,outbuf, szNUM
%warning %1 number
popa
%elifid %1
pusha
sc lstrcat,outbuf, %1
popa
%warning %1 Identifier
;%elifidni  dVal %1
%else
%ifdef dVal
%defstr %%temp %1
%substr %%token %%temp 2,-1
%warning %%token
%deftok %%tok %%token
pusha
sc wsprintfA,szNUM,"%0X ",dword %%tok
sc lstrcat,outbuf, szNUM
popa
%warning %%tok dword value
%else
%warning %1 else
%endif
%endif
%rotate 1
%endrep
puts outbuf ;print the buffer to the console
mov edi,outbuf
mov ecx,256
call memsetz  ;clear the buffer
%pop
%endm

%idefine szPTR
%idefine dVal&

This allows me to things like:
Code: [Select]
  writeLn "number: " ,3,szPtr TAB,szPtr outfile,szPtr NewLine
    mov edx,0FFh
    writeLn "value in edx: ",dVal edx
    writeLn "Address of infile:" ,szPtr TAB, dVal infile
    writeLn szPtr infile

Thanks Bryant for your example.
I have  played around a bit with it.

writeLn ax
produces:
%warning %1 address
it should produce:
%warning %1 register

I modified it slightly and it produces:
Code: [Select]
%macro writeLn 1-*
%rep %0
%ifstr %1
%warning %1 string
%elifnum %1
%warning %1 number
%else
%push
%defstr %$id %1
%strlen %$idlen %$id
%substr %$first_char %$id 1
%substr %$last_char %$id %$idlen

%ifidni %$first_char,'['
%ifidni %$last_char,']'
%warning %$id pointer
%else
%warning invalid pointer
%endif
%else
%if %$idlen = 3
%substr %$reg %$id 2,3
%strcat %$reg %$id
%warning define  %$reg
%elif %$idlen = 2
%define %$reg %1
%warning define %$reg
%else
%define %$reg
%warning define %$reg
%endif

%ifidni %$reg,ax
%warning %1 register
%elifidni %$reg,bx
%warning %1 register
%elifidni %$reg,cx
%warning %1 register
%elifidni %$reg,dx
%warning %1 register
%elifidni %$reg,si
%warning %1 register
%elifidni %$reg,di
%warning %1 register
%elifidni %$reg,sp
%warning %1 register
%elifidni %$reg,bp
%warning %1 register
%elifidni %$reg,al
%warning %1 register
%elifidni %$reg,bl
%warning %1 register
%elifidni %$reg,cl
%warning %1 register
%elifidni %$reg,dl
%warning %1 register
%elifidni %$reg,ah
%warning %1 register
%elifidni %$reg,bh
%warning %1 register
%elifidni %$reg,ch
%warning %1 register
%elifidni %$reg,dh
%warning %1 register
%elifidni %$reg,cs
%warning %1 segment register
%elifidni %$reg,ds
%warning %1 segment register
%elifidni %$reg,es
%warning %1 segment register
%elifidni %$reg,gs
%warning %1 segment register
%elifidni %$reg,fs
%warning %1 segment register
%elifidni %$reg,ss
%warning %1 segment register
%else
%warning %1 address
%endif
%endif
%pop
%endif
%rotate 1
%endrep
%endmacro

Code: [Select]
\nasm\bin\nasm -f win32 "C:\Nasm\iTop\Project\writeLn\writeLn3.asm"
C:\Nasm\iTop\Project\writeLn\writeLn3.asm:87: warning: (writeLn:82) 1 number
C:\Nasm\iTop\Project\writeLn\writeLn3.asm:87: warning: (writeLn:82) "hello" string
C:\Nasm\iTop\Project\writeLn\writeLn3.asm:87: warning: (writeLn:82) define 'eax'
C:\Nasm\iTop\Project\writeLn\writeLn3.asm:87: warning: (writeLn:82) eax address
C:\Nasm\iTop\Project\writeLn\writeLn3.asm:87: warning: (writeLn:82) '[ebx]' pointer
C:\Nasm\iTop\Project\writeLn\writeLn3.asm:88: warning: (writeLn:82) define ax
C:\Nasm\iTop\Project\writeLn\writeLn3.asm:88: warning: (writeLn:82) ax register
C:\Nasm\iTop\Project\writeLn\writeLn3.asm:88: warning: (writeLn:82) define bx
C:\Nasm\iTop\Project\writeLn\writeLn3.asm:88: warning: (writeLn:82) bx register
C:\Nasm\iTop\Project\writeLn\writeLn3.asm:88: warning: (writeLn:82) define cx
C:\Nasm\iTop\Project\writeLn\writeLn3.asm:88: warning: (writeLn:82) cx register
C:\Nasm\iTop\Project\writeLn\writeLn3.asm:88: warning: (writeLn:82) define dx
C:\Nasm\iTop\Project\writeLn\writeLn3.asm:88: warning: (writeLn:82) dx register
C:\Nasm\iTop\Project\writeLn\writeLn3.asm:88: warning: (writeLn:82) define 'esp'
C:\Nasm\iTop\Project\writeLn\writeLn3.asm:88: warning: (writeLn:82) esp address
C:\Nasm\iTop\Project\writeLn\writeLn3.asm:89: warning: (writeLn:82) define al
C:\Nasm\iTop\Project\writeLn\writeLn3.asm:89: warning: (writeLn:82) al register
C:\Nasm\iTop\Project\writeLn\writeLn3.asm:89: warning: (writeLn:82) define bh
C:\Nasm\iTop\Project\writeLn\writeLn3.asm:89: warning: (writeLn:82) bh register
C:\Nasm\iTop\Project\writeLn\writeLn3.asm:89: warning: (writeLn:82) define dl
C:\Nasm\iTop\Project\writeLn\writeLn3.asm:89: warning: (writeLn:82) dl register
C:\Nasm\iTop\Project\writeLn\writeLn3.asm:89: warning: (writeLn:82) define dh
C:\Nasm\iTop\Project\writeLn\writeLn3.asm:89: warning: (writeLn:82) dh register
C:\Nasm\iTop\Project\writeLn\writeLn3.asm:89: warning: (writeLn:82) define cl
C:\Nasm\iTop\Project\writeLn\writeLn3.asm:89: warning: (writeLn:82) cl register
C:\Nasm\iTop\Project\writeLn\writeLn3.asm:89: warning: (writeLn:82) define ch
C:\Nasm\iTop\Project\writeLn\writeLn3.asm:89: warning: (writeLn:82) ch register
C:\Nasm\iTop\Project\writeLn\writeLn3.asm:90: warning: (writeLn:82) define 'ebx'
C:\Nasm\iTop\Project\writeLn\writeLn3.asm:90: warning: (writeLn:82) ebx address
C:\Nasm\iTop\Project\writeLn\writeLn3.asm:90: warning: (writeLn:82) define 'edx'
C:\Nasm\iTop\Project\writeLn\writeLn3.asm:90: warning: (writeLn:82) edx address
C:\Nasm\iTop\Project\writeLn\writeLn3.asm:90: warning: (writeLn:82) define 'ecx'
C:\Nasm\iTop\Project\writeLn\writeLn3.asm:90: warning: (writeLn:82) ecx address
C:\Nasm\iTop\Project\writeLn\writeLn3.asm:90: warning: (writeLn:82) define 'edi'
C:\Nasm\iTop\Project\writeLn\writeLn3.asm:90: warning: (writeLn:82) edi address
C:\Nasm\iTop\Project\writeLn\writeLn3.asm:91: warning: (writeLn:82) define cs
C:\Nasm\iTop\Project\writeLn\writeLn3.asm:91: warning: (writeLn:82) cs segment register
C:\Nasm\iTop\Project\writeLn\writeLn3.asm:91: warning: (writeLn:82) define ds
C:\Nasm\iTop\Project\writeLn\writeLn3.asm:91: warning: (writeLn:82) ds segment register
C:\Nasm\iTop\Project\writeLn\writeLn3.asm:91: warning: (writeLn:82) define es
C:\Nasm\iTop\Project\writeLn\writeLn3.asm:91: warning: (writeLn:82) es segment register
C:\Nasm\iTop\Project\writeLn\writeLn3.asm:91: warning: (writeLn:82) define gs
C:\Nasm\iTop\Project\writeLn\writeLn3.asm:91: warning: (writeLn:82) gs segment register

Make done.

Thankyou very much for your contributions

Klod