is there any way i can put data in the .code section of the program because i do not want to have a data section.

also, can you tell me what the $ does in ASM, i know it was used to terminate srings in DOS, but i saw it in code for the win32.

Thanks
Posted on 2001-07-27 21:45:22 by SubHuman
$ is the current address in the file. Example:

MyData:
dd 1
dd 2
dd 3
MySize EQU $-MyData ;MySize = 12

You can put data in the code section, but you have to make the code section writable. This can be achieved with the link option: /SECTION:.text,EWR

Another option is to only have constant data and write everything to the stack - this is a little harder. :)
Posted on 2001-07-27 23:00:51 by bitRAKE
Yes, you can put data in the code section, but there are good reasons why you shouldn't. I suggest that you read Agner Fog's optimization guide. :)
Posted on 2001-07-27 23:43:48 by S/390
You can put the data in your .data section, then combine data+code
sections at link time (read linker docs... or the output of "link" with
no parameters). And do remember to make codesection writable.

S/390: why shouldn't you put data in the code section? Apart from
suboptimal page sharing, that is :)
.
Posted on 2001-07-28 09:43:02 by f0dder
thankyou for your help.

Also, where can i get the optimization guides, at the moment my code is somewhat ineficient, and i would like to see how i can improve it
Posted on 2001-07-28 12:00:07 by SubHuman
Here you got SubHuman:

http://www.agner.org/assem/

Cheers!

Latigo
Posted on 2001-07-28 15:11:43 by latigo
subvirus, don't listen to any of them. they're evil. :grin: follow your heart.

and for the anger's help file, it's in c:\masm32\help or helpfile.

to make .CODE readable, use the following directive:

option casemap:none, noreadonly

and you're done.

reason why they say is not a good idea to put data into code section:

cpu is constantly executing instruction in sequent order. and it can't destinquish the difference between data and code. so, it will attempt to execute it no matter what.



.code
myage db ?
welcome db "in assembly we trust!", 0

;;;code begins;;;;


now, take a careful look here. what's the point of having data in code that will never run? (i'm sure you know that you don't want your data to be execute. right?) therefore, it's useless and you're making it hard for yourself by using Segment Override (which is something you should AVOID whenever you can!) and also, in dos, you have to place the JUMP before your data begins. thus, taking up a few bytes (and it's not good to have jump. you should always reduce them to the best of your ability)

but there's a way around this. have a look at the asm file. group those two segment together.
Posted on 2001-07-28 17:27:58 by disease_2000
Disease, you're talking about things you have no clue about. Sorry,
that sounded harsh, but it is true. Right now I'm sorta drunk, so I
will not do a <qoute> + </quote> listing of your errors, but I COULD
do that when I'm sober :).

There are reasons to use separate code/data sections under windows,
just look at how the windows memory management is done...
if any clarifications are needed, wait between six to twelve hours and
I will elaborate.
Posted on 2001-07-28 18:17:34 by f0dder
Guys,

its technically trivial to put data in the code section, just use a jump and a label and write the data between the two. Reading it is easy but writing to it is a problem unless you want to change the attributes of the code section to /WRE( write/read/execute).

You have the other choice of copying the data to a stack variable if you want to write to it. s/390 has a good point in that it is not the most efficient way to utilise the CPU by putting data in the code section but unless the section of code is properly speed critical in recursion, you will get away with it and not notice the difference.

regards,

hutch@pbq.com.au
Posted on 2001-07-28 20:22:04 by hutch--

/390 has a good point in that it is not the most efficient way to utilise the CPU by putting data in the code section but unless the section of code is properly speed critical in recursion, you will get away with it and not notice the difference


Please tell me why. I cannot find any logical reasons for this :/
Posted on 2001-07-28 21:24:20 by f0dder
It seems to me that merging code + data section by the linker isn't that problematic, since code and data reside in separate 'blocks'. It *is* problematic to put inline data snippets inside code. The "AMD Athlon Processor Code Optimization Guide" says:

Avoid Placing Code and Data in the Same 64-Byte Cache Line
Sharing code and data in the same 64-byte cache line (Note: 32 byte on PPro/PII/PIII) may cause the L1 caches to thrash (unnecessary castout of code/data) in order to maintain coherency between the separate instruction or data caches. ... Avoid placing code and data together within this larger cache line, especially if the data becomes modified.
Posted on 2001-07-29 09:17:08 by -SMK-
yes f0dder. that's how i learn. i first have to assume that i'm right. and if i'm wrong, people will correct me. (people never assume that they're wrong. cause if they do, they wouldn't do things that they dream of. the wrong things is what get people going)

one thing i forgot to say f0dder. once you get back, please do me a favor and list the thing that is wrong in my respond (and please, be reasonable. don't tell me that my definition of $ is wrong. it has nothing to do with money. i was joking at the time of posting that msg) so i learn
Posted on 2001-07-29 11:35:01 by disease_2000
Disease, I think I was a bit too harsh in my previous post - sorry.



cpu is constantly executing instruction in sequent order. and it can't
destinquish the difference between data and code. so, it will attempt
to execute it no matter what.


This has something right and something wrong in it. It's true the processor
doesn't know the difference between data and code, and doesn't care at all.
But it will only being executing data if you "acidentally" fall through to
the data. But this can also happen if you have data in the .data section.
Splitting code and data in sections doesn't really do magic - all it does is:

align sections in memory to (at least) a 4k boundary, so the x86 paging
mechanism can be used to assign different permissions to page access.
And of course grouping data and code separately, which matters more to a human
doging debugging than it matters to the CPU (except for when code and data
is placed "too close", like SMK pointed out).



now, take a careful look here. what's the point of having data in code that
will never run?


Placing data and code in the same section, whether by linker-section-merging
or manually putting your variables in .code, has the advantage of using only
one section, avoiding 512byte (or more...) FileAlign between sections. Doesn't
often matter, but sometimes it can give those few extra bytes you need.



(i'm sure you know that you don't want your data to be execute. right?)


Putting data in .data doesn't make it non-executable. The executable bit is
specified in descriptors, not at a page level. Since we run under a 32bit flat
mode, CS and DS points to the same area, and thus there's no execute protection
possible (the OS scheduler could take care of this, but it would make task/thread
switching a lot slower).



therefore, it's useless and you're making it hard for yourself by using
Segment Override (which is something you should AVOID whenever you can!)


You don't need any segment overrides, since we're in 32bit flatmode. And as long
as you make the code section RWE, you're not making anything harder for yourself.


and also, in dos, you have to place the JUMP before your data begins. thus, taking
up a few bytes (and it's not good to have jump. you should always reduce them to
the best of your ability)


You didn't have to do that placement stuff. It's true that many people did this in
COM files, but you didn't have to - you could easily place code first, the data when
all the code was done, and then you wouldn't need any extra jumps. EXE files did not
have this problem at all. And by the way, unconditional jumps don't hurt very much.
Posted on 2001-07-29 14:49:26 by f0dder
Really, you only need code sections and the linker will organize the code sections for you, but you still need to make the code section writeable if you don't store everything locally on the stack. This also gives me an inline way to write the SWITCH/CASE macro.
Posted on 2001-07-29 15:46:29 by bitRAKE
$-grouped sections are nice - but don't always work like you expect!
When dealing with import sections (.idata), the grouping is done in
a VERY weird way :).
Posted on 2001-07-29 15:50:01 by f0dder
How do they work? This is very important to making some cool macros, that would otherwiae be impossible. If you have more information that would be great.
Posted on 2001-07-29 15:52:41 by bitRAKE
Hi Fodder,

The mixture of the data and code inside program was the base of our computers and processors for a long time (since the beginning)... its called a TURING Machine/Architecture...

I like this a lot, and FORTH (my loved HLL) is very much based on this (also on virtual machine). i belive this alows a algorithms to be implemented......

BUT:

Today's procesors still expose a TURING Machine /Architecture to the external world, but inside they have a HARWARD Machine Architecture, this architecture has separated pathd for CODE and DATA... such a machine is faster and acomodates CACHE much better ;)

This is done with a vaste of space and destruction of an important principle: general machine. But todays king is SPEED because of lazy HLL that need every help they can get...

Because of this internal HARWARD Machine Architecture one should NOT mix DATA and CODE anymore if possible....

As Hiro stated it you can still get by with it....but u will never know in the FUTURE ;)

You are also missing the point (but there is no point Oblio ;) )
at the jump usage, what is meant is NOT the JMP at the start of old DOS .COM code... bit this:



.CODE

JMP over _this_string

sz_string db "this is a string, hence data inside code",0

over_tihis_string:
mov eax,offset sz_string
call my_print_string_routine ; use MessageBoxA

; more code here
......





doing this is a very simple way of mixing data and code used in the sz_string MASM macro...this will slow down your code a little bit because of cache trash but you will not notice or care if that section of code will not be intensive ...

a simple change of the macro will deal with this slowdown ( place .DATA and .CODE around string definition) and eliminate code/data mixture

THERE is no data/code execute protection because WIN Os was lazy implementing it... and because of legacy HLL compilers at the time of Win OS developement ....

its not a direct consequence of FLAT 32 bit mode... its just the most simple and most easy way of doing a 32 bit system ;) CS and DS can have totaly diffrent selectors and with diffrent EXECUTE flags.....

besides the fact that CS and DS selectors point to the same memory dosent means one can execute data ...because CS is allways used to read IP register...and its selector is diffrent from DS's selector

yes one can fall thru or jump or can move sections of code from/to data but that could be stopped also IF OS ever wanated to....

I dont like it personally but the future is in the HARWARD Architecture (because of speed) and into separated DATA and CODE streams ...
Posted on 2001-07-29 15:55:58 by BogdanOntanu
Bogdan, it IS a consequence of the flat 32bit architecture. Flat means
all (general) descriptors are set up with base0 and limit4G. Sure,
the CS will not be writeable, but then you just use DS (which adresses
the same memory range). If you want to execute data, just reference
it with CS. If you change this scheme, it will not be FLAT anymore.

Interleaved data and code is stupid. First there's the cache issues,
then there are the fact the "jmp jump_over_data" adds a little extra
code.

As data/code separation being wasteful... you will only lose a very
few bytes in most applications. I mean, sure, sections are aligned
to 4k in memory, so you can max waste 4k-1 byte...not very much
these days. And you will typically lose much less, when you do "real"
applications and not useless "tiny tests" :).

Stopping falllthrough / data execution in a FLAT(!) 32bit system
would require the thread/task scheduler to see if EIP is inside a
section that has "execute" set - this being on an OS-logic level, not
processor hardware level. This would slow down scheduling a lot,
and wouldn't be very failsafe --- you could still execute data that is
stored in code section. A 1byte displacement would still be in the
code section, but give garbage opcodes. Et cetera.
Posted on 2001-07-29 16:05:32 by f0dder
I didn't think we were talking about placing your data before or after your code. I don't think it makes much difference in this case. But there are performance issues when you jump around data embedded in instructions.

The cache has already been mentioned. Here's another problem. The CPU fetches 16 byte "chunks" of code at a time, places it in an internal buffer and starts to decode it. There are 2 such buffers, so the CPU pre-fetches 32 bytes. It has no idea what is in these 32 bytes, but assumes that it is code. When it contains data, that data is needlessly fetched from memory and takes up space in the buffers. The CPU contains 3 decoders, so it can work on up to 3 instructions at a time. If the buffers contain data, this reduces the chances of having enough instruction information in the buffers to keep the 3 decoders busy.

The extra jump around the data also slows things down. Plus even unconditional jumps take an entry in the branch prediction buffer (BPB). So the extra jump has a good chance of causing a "valid" jump to be evicted from the BPB.

:)
Posted on 2001-07-29 22:13:10 by S/390
can anyone tell me what a delta offset is?

thanks
Posted on 2001-07-30 11:26:17 by SubHuman