I was bored and started playing around with C Style strings. After reading a post about puting data into the .code section, I posted my own little trick and I figured to write a macro and test it out. When I created it, I tested it against CTEXT and SADD. The program I created was just a simple MessageBox using the different macro's for the title and the message. The resulting programs ended up like this:
(Note: only thing different is the macro in the programs)

SADD: filesize = 3.00 KB
CTEXT: filesize = 2.50 KB
SVAR: filesize = 2.50 KB

SVAR actually does use a jump-skip method that I know is not very popular, but when I ran the programs side by side, SVAR ran just a little faster than CTEXT. If nyone has any optimizations or suggestions for this little macro, post back.

svar macro x:VARARG
local _x
jmp @f
BYTE x,0
@@: mov eax,_x
exitm <eax>

Well, have fun with it, and if you find different speed or size results than what I did
that completely disagrees with my findings, then definately let me know.

Thanks in advance for any responces,
Bryant Keller
Posted on 2004-05-29 22:15:01 by Synfire
My only comment would be that data in the code section is not recommended for optimal code according agners guide anyway. Though I haven't studied it in detail yet.
Posted on 2004-05-30 06:04:22 by Eóin
What I don't like about using SADD, is that it has an 'align 4' instruction. So EVERYWHERE you use it, it adds 'align 4' which effectively (in my oppinion) wastes clock cylces in most cases! This (in my oppinion) accounts for the difference in sizes when using SADD. I personally, use a very similar method to CTEXT. Although CTEXT allocates memory in the .data segment, I prefer to allocate memory in the .const segment. One of the problems with using memory allocated with your method is, the .code segment has PAGE_EXECUTE_READ 'access protection' enabled. Also, your method trashes eax to store the address. Note: I'm only trying to provide constructive criticism here! You would have to be careful where and when you use your method, as you'ld have to remember not to use eax when using the macro. I'm thinking in terms of the INVOKE macro handler that also uses eax under certain conditions! I'm noticed some discrepencies when using INVOKE and eax register. I use this:
sz MACRO inText

LOCAL tmpString, SegName
SegName TEXTEQU @CurSeg
tmpString db inText, 0
@CurSeg ENDS
EXITM <offset tmpString>
What it does is store the current segment (.code, .data etc) allocate memory in the .const segment, then return to the current segment. I needed to add the segment handling code because I sometimes allocate strings inside structures which are in turn allocated in the .data segment. It's just safer to allow it to return 'gracefully' to whatever segment it was called from! Hope it helps you with your own ideas!

Posted on 2004-05-31 04:44:39 by SubEvil
thanks for all of the comments, and as I said I am fully aware that putting data within the code segment is frowned upon (and as I said I rarely use this method except when doing some basic debugging).

I totally didn't think about eax corruption, it just slipped my mind. so I went back and changed it so it doesn't use eax now.

var macro x:VARARG
local _x
jmp @f
BYTE x,0
exitm <OFFSET _x>

Thanks again for all of the suggestions.

Bryant Keller
Posted on 2004-05-31 22:04:42 by Synfire

Hehehehe, your method is now EXACTLY the same as CADD in the MASM32 library, check it out, the only difference is that the CADD has an 'align 4'. Talk about re-inventing wheels ;) Something I find myself doing over and over again, thinking that what I've done, hasn't been done before :grin: Anyway, when you re-invent wheels, you (usually) learn a whole bunch of other things! :alright:


PS: Even for debug purposes, I have no idea why anyone would want to put 'string data' in the .code segment! I can think of only 1 reason, for size, because you 'potentially' don't need another segment, you can embed all your 'data' in the .code segment. But even then, if you wanted that, you can merge the segments at link time anyway, so there's still no 'justifiable' reason to do it, in my mind! Because at the end of the day, the merge method still sounds better because you don't need the jmp instructions, and the result is the same! Anyway, everybody to their own!
Posted on 2004-06-01 01:06:52 by SubEvil
data in code segment = bad. Align 4 = good. Simple as that. "Align 4" wastes max. 3 bytes, and if you do string copying in dword blocks, unaligned dword access can be semi-nasty. The following macro works from any segment and puts the stuff in the CONST segment - pretty easy to add alignement or change segment if you want. Can't remember who posted it originally, but probably it's either from bitRAKE or scali or ewald.


CONST segment
IFIDNI <y>,<>
sym db 0
sym db y,0
CONST ends

...works like a charm, anyway.


...works like a charm, anyway,
Posted on 2004-06-01 11:31:19 by f0dder
thanks, haven't seen CADD yet. And what I meant by "debugging purposes" is that I commonly, when debugging software that is crashing, I print out a message box (or a string to stdout depending on if it is a console app or not) containing the line number and the instructions. I skip every 19 lines and put one of those print statments there as to find out about where the bug is.

This means that my final product usually doesn't have things like SVAR, SADD, or CTEXT in it anyways, only when looking for errors.

Also, I was looking for an alternative to CTEXT because when using /MERGE:.data=.text /MERGE:.code=.text /MERGE:.const=.text etc. the file size of CTEXT stays at 2.50 KB while SVAR will drop down to 2.00 KB.

I'll definately look into CADD, and I appreciate all the suggestions. Thanks alot!

Bryant Keller
Posted on 2004-06-01 12:26:56 by Synfire
Personally, I do not like this approach! Although the 'CONST segment' might 'look' like the .const segment, it isn't. You are creating a 'custom' designed segment with 'default' access protection. But the fact remains, an additional 512 byte segment will be created just for your string data. You can effectively call this custom designed segment anything you like! For example 'STRING segment'. But the fact remains, it isn't the 'real'/default .const segment! Of course if you wanted it there, you could merge your custom segment and the .const segment, but that is an additional step. The MACRO I proposed doesn't need the additional step, as the data sits in .const already! Anyway, whatever you prefer!

Posted on 2004-06-02 02:14:26 by SubEvil