News:

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

Macro expansion problem

Started by stanhebben, July 01, 2006, 02:51:28 PM

Previous topic - Next topic

stanhebben

I needed a macro which was similar to print, but which does preserve all registers and flags.

So this was what I wrote:

debug macro args:vararg
  pushad
  pushfd
  print args
  popfd
  popad


No problem on first sight, but when I wrote the following:

debug ustr$(eax)

I noticed that eax got changed.

When disassembling my program, I see that eax gets converted to a string first, then it executes pushad/pushfd, prints the contents, and pops the registers off the stack.

Is there any way to solve this?

Thanks.

hutch--

Stan,

I think I have run into the problem before, the macro engine in MASM tends to run complete macros in order then run bits of the code after it and this messes up what you are trying to do. I think you can do it by doing the direct API call in the macro rather than calling the macro in the middle and this will probably work OK.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

Ossa

I haven't tried this (and I don't use print or any other of the macros there, so I'm quite unsure), but this might help:

debug macro args:vararg
  pushad
  pushfd
% print args
  popfd
  popad


debug <ustr$(eax)>

I don't have the time to check at the moment, sorry.

Ossa
Website (very old): ossa.the-wot.co.uk

MichaelW

Stan,

As Hutch stated, the problem is the order in which the macros are expanded. EAX is changed when there is a macro function in the debug macro arguments. I tested Ossa's idea and it does not correct the problem, but perhaps there is some other method of controlling the order of the macro expansion.

0040103E B878563412             mov     eax,12345678h
00401043 681E304000             push    40301Eh
00401048 50                     push    eax
00401049 E892000000             call    fn_004010E0
0040104E 90                     nop
0040104F 60                     pushad
00401050 9C                     pushfd
00401051 681E304000             push    40301Eh
00401056 E8B1000000             call    fn_0040110C
0040105B 682C304000             push    40302Ch
00401060 E8A7000000             call    fn_0040110C
00401065 9D                     popfd
00401066 61                     popad
00401067 90                     nop


Replacing the macro function in the arguments with a direct API (or macro) call would fix the problem, but it would limit the macro to a particular data type and output. A more flexible solution would be to use crt_printf to generate the output.

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

    debug macro args:vararg
      nop
      pushad
      pushfd
      print args
      popfd
      popad
      nop
    endm

    _debug macro format, args:vararg
      nops 2
      pushad
      pushfd
      invoke crt_printf, reparg(format), args
      popfd
      popad
      nops 2
    endm

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    .data
    .code
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
start:
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    mov eax, 12345678h
    debug "debug",13,10
    print uhex$(eax),"h",13,10,13,10

    mov eax, 12345678h
    debug uhex$(eax),"h",13,10
    print uhex$(eax),"h",13,10,13,10

    mov eax, 12345678h
    _debug "%xh%c",eax,10
    print uhex$(eax),"h",13,10

    inkey "Press any key to exit..."
    exit
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end start

output:

debug
12345678h

12345678h
00000031h

12345678h
12345678h
Press any key to exit...
eschew obfuscation

Ratch

     Where are uhex$ and ustr$ defined?  Ratch




MichaelW

eschew obfuscation

stanhebben

Ossa's method does work for me:


debug macro args:vararg
pushad
pushfd
% print args
popfd
popad
endm

mov eax, 1
debug <ustr$(eax)>,13,10

.text:00401505   mov     eax, 1
.text:0040150A   pusha
.text:0040150B   pushf
.text:0040150C   push    0Ah
.text:0040150E   push    offset unk_40328F
.text:00401513   push    eax
.text:00401514   call    ds:_ultoa
.text:0040151A   add     esp, 0Ch
.text:0040151D   push    offset unk_40328F
.text:00401522   call    sub_4018B8
.text:00401527   push    offset asc_4032A4 ; "\r\n"
.text:0040152C   call    sub_4018B8
.text:00401531   popf
.text:00401532   popa


I don't get you it doesn't work for you - you're sure you didn't forget the %?

As this is the easiest method, I'll use it.

Thanks Ossa.

Stan

MichaelW

Yes, it does work, when I implement it correctly :red
eschew obfuscation