Here is a macro showing the size of your code. Question: Is there any clean way to determine the size of the code that has been added by the Masm32 libraries? I assume searching for the byte sequence 004015F4 in the code would be an option, but that might be OS-specific...
CPU Disasm (from OllyDbg)
Address Hex dump Command Comments
004015F4 $- FF25 D0224000 JMP DWORD PTR DS:[<&kernel32.ExitProcess
004015FA $- FF25 D4224000 JMP DWORD PTR DS:[<&kernel32.GetStdHandl
Thanx, jj
ShowCodeSize MACRO
call ChkEnd
sub eax, offset start
push eax
print chr$(13, 10, "Your own code section has ")
pop eax
print ustr$(eax)
print chr$(" bytes", 13, 10, 10)
ENDM
... code ...
OPTION PROLOGUE:NONE
OPTION EPILOGUE:NONE
ChkEnd2 proc
int 3 ; for testing in OllyDbg
mov eax, [esp]
ret
ChkEnd2 endp
ChkEnd proc
call ChkEnd2
ret
ChkEnd endp
OPTION PROLOGUE:PrologueDef
OPTION EPILOGUE:EpilogueDef
Quote from: jj2007 on June 26, 2008, 10:01:27 AM
Question: Is there any clean way to determine the size of the code that has been added by the Masm32 libraries? I assume searching for the byte sequence 004015F4 in the code would be an option, but that might be OS-specific...
you can define a text$z segment:
.code
[your code]
.code _text$z
ENDCODE equ $
And ENDCODE will be behind any code the linker has added.
OPTION PROLOGUE:NONE
OPTION EPILOGUE:NONE
[snip]
OPTION PROLOGUE:PrologueDef
OPTION EPILOGUE:EpilogueDef
There's no need for these directives if the procs between them don't contain params or locals.
Thanxalot! But wouldn't the segment be page-aligned...? I had embarked on a more complicated way, see below.
BeforeChkEnd:
ShowCodeSize proc uses esi
print chr$(13, 10, "Your code section has", 9)
mov eax, offset BeforeChkEnd - offset start
print str$(eax)
print chr$(" bytes ", 40, "excluding the ShowCodeSize routine", 41, 13, 10)
print chr$("The libraries added", 9)
mov esi, offset AfterChkEnd
xor ecx, ecx ; counter
@@: inc esi
mov eax, [esi]
inc ecx
cmp ecx, 4000
ja @F
cmp ax, 25FFh ; a long JMP
jne @B
mov eax, [esi+6]
cmp ax, 25FFh ; another long JMP exactly 6 bytes later
jne @B
@@: print ustr$(ecx)
print chr$(" bytes", 13, 10, 10)
ret
ShowCodeSize endp ; just before end start
AfterChkEnd:
end start
> Thanxalot! But wouldn't the segment be page-aligned...? I had embarked on a more complicated way, see below.
Not page-aligned, but possibly dword (.386) or para (16-bytes, .486 and above) aligned. The COFF linker will combine all sections beginning with _text until the '$', sort them by name and put them into a "physical" section. IIRC that's part of the COFF specification.
I tried your suggestion and got this:
Your code section has 1014 bytes (excluding the ShowCodeSize routine)
The libraries added 427 bytes (my cmp ax, 25FFh routine)
The linker added 4202496 - 4199422 = 3074 bytes
BeforeChkEnd:
ShowCodeSize proc uses esi
print chr$(13, 10, "Your code section has", 9)
mov eax, offset BeforeChkEnd - offset start
print str$(eax)
print chr$(" bytes ", 40, "excluding the ShowCodeSize routine", 41, 13, 10)
print chr$("The libraries added", 9)
mov esi, offset AfterChkEnd
xor ecx, ecx ; counter
@@: inc esi
mov eax, [esi]
inc ecx
cmp ecx, 4000
ja @F
cmp ax, 25FFh ; a long JMP
jne @B
mov eax, [esi+6]
cmp ax, 25FFh ; another long JMP exactly 6 bytes later
jne @B
@@: print ustr$(ecx)
print chr$(" bytes", 13, 10)
mov esi, offset ENDCODE
print chr$("The linker added", 9)
print str$(esi)
print " - "
mov eax, offset BeforeChkEnd
print str$(eax)
print " = "
sub esi, offset BeforeChkEnd
print str$(esi)
print chr$(" bytes", 13, 10, 10)
ret
ShowCodeSize endp
AfterChkEnd:
.code _text$
ENDCODE equ $
end start
Practical example:
UseOldCat = 1
Your code section has 1162 bytes (excluding the ShowCodeSize routine)
The libraries added 430 bytes
UseOldCat = 1
Your code section has 653 bytes (excluding the ShowCodeSize routine)
The libraries added 331 bytes
Look for the UseOldCat switch in the attachment.
EDIT:
In contrast to the old cat$ macro, CAT$ does not require buffer initialisation:
old cat$:
mov byte ptr [mcDefBuffer], 0 ; clear the target buffer for cat$
mov eax, cat$(addr mcDefBuffer, CrLf$, "Ciao bello")
new CAT$:
mov eax, CAT$(0, CrLf$, "Ciao bello")
is the same as
mov eax, CAT$(addr mcDefBuffer, CrLf$, "Ciao bello")
i.e. passing a zero pointer means use the mcDefBuffer default buffer. In any case, CAT$ will write to the pointer "as is", i.e. will not check for a terminating zero byte. If you need the "append to myBuffer" functionality, use:
mov eax, CAT$(addr myBuffer, CrLf$, "Ciao bello")
mov eax, CAT$(1, CrLf$, "This line was appended")
The mcDefBuffer hangs around in the .data? section and has 1024 bytes, i.e. a very big MessageBox.
When used with CAT$(0, ...), the copy is safe, i.e. will never write beyond the buffer.
When using other buffers, the copy is not safe.
[attachment deleted by admin]