News:

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

Quick way to Update to Masm(ml.exe) 9

Started by ecube, March 26, 2009, 04:01:46 PM

Previous topic - Next topic

donkey

Quote from: mitchi on March 29, 2009, 04:02:38 AM
The search for the smallest code, the fastest code and the smallest executable, these are common mental illnesses among us  :green

Nope, the search for a pointless optimization that might save 10 seconds over the entire lifespan of the program but takes 6 hours to implement, not one of my mental illnesses, though I have many others.
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

hutch--

 :bg

And the secret is ".rloc" as to why POLINK saves 512 bytes on an EXE file. ML.EXE uses the later DLL mainly to ensure it will not run on a standard earlier OS version, Microsoft have done this for years. A linker is a linker is a linker, basically it plonks the appropriate startup code at the front of the executable code, with PE files it structures the sections complete with the required alignment and positions the entry point.

Having used POLINK for years it is up to date specification wise and is generally MORE UP TO DATE than Microsoft link.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

Vortex

OK, I should be more precise to explain some facts. jj2007's example has nothing wrong and we know all about some fundemental principals of the PE specification. To be honest, an application running on a 32-bit OS will allocate a minimum of 4096 bytes in memory. Prefering Polink means that your application will not contain those junk bytes inserted by link.exe. Finally, the size difference is a result depending on how you interpret the PE specification. As Hutch stated Polink reflects a more precise usage of the specification. Personaly, I am not a fanatic of squeezing PE sections to get the minimal size : My tools on my website are not built with the /SECTION directive to merge sections and I don't use EXE compressors.

If someone decides to create his own llinker, that would probably be something similar to Polink in terms of dealing with the PE specification as there is no reason to insert unnecessary bytes to the executable built with the linker.

Mark, here is an exmple :

A typical application like Iczelion's tutorial #3, ( the blank window example ) has a size of 1536 bytes when linked with Polink ( link.exe -> 2560 bytes )

jj2007

Quote from: Vortex on March 29, 2009, 09:08:54 AM
OK, I should be more precise to explain some facts. jj2007's example has nothing wrong

Erol, thanks for the detailed clarification. There is a rumour that the new versions of link increases executable sizes and/or introduces "dependencies", but until now I have not seen any concrete examples - that's what I wanted to show. As to polink, it does produces somewhat smaller executables, but it is a matter of taste whether one accepts the 512 extra bytes or not  :bg

Attached a screenshot comparing the sections created by polink and link. File sizes are 58880 and 59392

[attachment deleted by admin]

Vortex

I understand what you mean. No any problem. Probably, there was a rumour.

Jochen, thanks for the Peview analysis. It's one of the most powerful tools to study PEs and MS COFF object files.

Mark Jones

Quote from: Vortex on March 29, 2009, 09:08:54 AM
A typical application like Iczelion's tutorial #3, ( the blank window example ) has a size of 1536 bytes when linked with Polink ( link.exe -> 2560 bytes )

Yes, this was very similar to my experience. On the particular piece of code I tested, there was a significant difference in size, and if the code is small like in this example, then the difference appears larger. This is why I gave a percentage estimate for a figure, because this was my observation with that particular executable. No lengthy trials were performed, nor did I say that I had conducted any lengthy trials...

I knew the reason why POLINK achieves smaller executables. But also consider that even though the "hardcore" programmers here make multi-megabyte executables in assembler, the majority of pure-assembler binaries are likely very small. Thus, the 512 bytes saved here and there amounts to a significant percentage of the (typical) executable size. In a 2MB binary, who cares about a few KB? That would be much better helped by an executable compressor like PECompact. But in a 5kB executable, 1kB is 20%. This just seems more important, because it is a larger percentage.

Alas, as Donkey says, spending hours of extra time to save a few bytes does not seem like a worthwhile investment. This is why I only observed this in passing -- spending any more time on it was pointless. (However, on the pedantic flip-side, if all executable code were created in assembler and as small as possible, how many Peta-Bytes of internet bandwidth would be freed monthly? How many Exo-Bytes of hard disk space would be freed?)

I gave up on the newer versions of ML and LINK when using AVG anti-virus. AVG was marking all MASM code as being infected (is it still?), so on a whim, I reassembled the code using the newest versions of ML and LINK at the time, and presto, AVG did not detect anything from that new executable. However, the executable was larger than the original, and I seem to recall it had a dependency on the latest CRT, or maybe the .PDB file as described previously. But this was some time ago, and my memory isn't the greatest.
"To deny our impulses... foolish; to revel in them, chaos." MCJ 2003.08

drizz

People,

POLink : creates smaller executables because it puts Import Directory in .data
MSLink : use /MERGE:.data=.rdata command
POLink : creates smaller executables because it defaults to 512 section alignment
MSLink : use /FILEALIGN:512 command

now stop the silly POLink vs MSLink debate.




Quote from: ToutEnMasm on March 26, 2009, 06:01:46 PM
Quote
          dizz says it is, and his listing show it is...herm idk
Perhaps he say it is corrected but he is wrong.
The bug is:
Quote
When masm push a byte in the stack , he need to translate it before to a dword.
He used different methods for that,in this case
invoke test1, ab                        ;ab is a byte in data
;------------- here what he do to perform this -------------------
00000041  A0 00000000 R   *       mov    al, ab
00000046  50         *       push   eax
00000047  E8 0000003C      *       call   test1
;--------------------------------------------------------------------------------------
he put ab in al,eax is modified
usually he just push the data and there is no register modify  (32 bits data)
What are you talking about?!???! What does your listing show?!
The truth cannot be learned ... it can only be recognized.

donkey

Quote from: ToutEnMasm on March 26, 2009, 06:01:46 PM
Quote
          dizz says it is, and his listing show it is...herm idk
Perhaps he say it is corrected but he is wrong.
The bug is:
Quote
When masm push a byte in the stack , he need to translate it before to a dword.
He used different methods for that,in this case
invoke test1, ab                        ;ab is a byte in data
;------------- here what he do to perform this -------------------
00000041  A0 00000000 R   *       mov    al, ab
00000046  50         *       push   eax
00000047  E8 0000003C      *       call   test1
;--------------------------------------------------------------------------------------
he put ab in al,eax is modified
usually he just push the data and there is no register modify  (32 bits data)

How do you expect to push a BYTE value onto the stack in 32 bit programming ? There is no such thing as PUSHB in 32 bit mode but if there was it would be exactly as above. Since the rest of EAX is of no importance it is undefined after the "PUSHB". I do not see this a bug at all, it is simply a way to execute a request that makes no sense in 32 bit programming with a quick fix. SO if you don't want EAX modified, (even though it is considered volatile) then don't try to perform task that are unsupported by the platform you are programming in.

Remember that in 32 bit mode you can only ever PUSH a DWORD, this is determined by the address-size attribute and nothing that any assembler can do, everything else is a fix up by the assembler to cover the asses of programmers who don't know this or choose not to follow the rules of the IA32 architecture. The only BUG here is that MASM lets you push a BYTE at all, it should throw an invalid operand error for the programmer who obviously doesn't understand the stack, or perhaps display a link to the Intel web site to complain that though you're using a 32 bit processor you still want to use 8 bit operands.

Edgar
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

Vortex

Hi Mark,

Yes, Donkey is right with his statement pointing that doing extra researches to perform some minor optimizations in large executables has no any practical value. That's true.

Me too, I have the same false positive problem with an AV software. Mark, you have other options :

a) Assemble the source code with the latest version of ml.exe
b) Instead of the newer version of link.exe, try to use Open Watcom's Wlink, Jeremy's GoLink or Pelle's Polink. There also Alink but it's an outdated product.

Quoteif all executable code were created in assembler

This should be the idea. For us the assembly coders, what's is difficult is not finding an algorithm simple or complicated but focussing our attention to create clean, easily understable and readable code. Using only assembly language to create applications should be mainly based on writing readable and maintainable code. It's easy to gain bad habits in programming but it takes a lot of efforts to learn how to write readable code. Careful indentation, casing standards, easily understable variables, good documentation and moving code portions to procedures are the elements of properly written code. Sometimes, I find myself struggling with my own code to understand what I was trying to do. I think we should create to a sticky topic about writing clean assembly code.

jj2007

Quote from: drizz on March 29, 2009, 04:31:51 PM
People,

POLink : creates smaller executables because it puts Import Directory in .data
MSLink : use /MERGE:.data=.rdata command
POLink : creates smaller executables because it defaults to 512 section alignment
MSLink : use /FILEALIGN:512 command
drizz,
No change of file size with your options. Stuck at 58880 for polink, 59392 for ms link, both old and newest version.

Quote
now stop the silly POLink vs MSLink debate.

There are no silly debates in this forum, except for the Colosseum and the Soap Box. We raised the question whether the newest version of MS link creates dependencies and increases file size substantially. That is an entirely sober and valid question for assembly programming. If you can bring solid evidence, everybody will be grateful.

GregL

Maybe you are thinking of the dependencies the Visual C++ 2003, 2005 and 2008 compilers produce.

    http://www.masm32.com/board/index.php?topic=9803.msg71774#msg71774

Also, with just MASM, if you link to the Visual C++ 2003, 2005 and 2008 versions of msvcrt.lib you will get these dependencies too.  If you link to the MASM32 version of msvcrt.lib you won't get them.


GregL


BlackVortex

QuoteMSLink : use /MERGE:.data=.rdata command
MSLink : use /FILEALIGN:512 command

I can't get those to work. They get (silently) ignored ? Using MS linker  9.00.21022.08 , will try others, too.

I compare the resulting executables and the only difference is the timestamp  :eek

Vortex

Hi drizz,

MSLink : use /MERGE:.data=.rdata command

You should be careful with the MERGE switch as it can lead you to a problem with section attributes :

LINK : warning LNK4254: section '.data' (C0000040) merged into '.rdata' (4000004
0) with different attributes


The linker shipped with VS 2008 Express Edition Sp1 (  V9.00.30729.01 ) creates the executable but the PE will crash.

This one works :

link /SUBSYSTEM:WINDOWS /FILEALIGN:512 /MERGE:.data=.rdata /SECTION:.rdata,RW Win.obj

To avoid any misunderstandings, none of us we intend to begin a Polink vs MS link debate.


jj2007

Quote from: Vortex on March 29, 2009, 07:22:04 PM

This one works :

link /SUBSYSTEM:WINDOWS /FILEALIGN:512 /MERGE:.data=.rdata /SECTION:.rdata,RW Win.obj


Well, kind of - it doesn't crash, but in my specific case it increases file size by a 1000% :boohoo:
Apparently, it doesn't like this construct:
.data?
align 4
  lbl LABEL byte
  ORG $+BufLen-1
  db ?


.data? becomes part of the .data initialised section...