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.
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.
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
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...
Where are uhex$ and ustr$ defined? Ratch
In masm32\macros\macros.asm
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
Yes, it does work, when I implement it correctly :red