I'm talking about this:
\masm32\examples\exampl01\minimum
Why using:
.code
start:
jmp mylabel
szDlgTitle db "Minimum MASM",0
szMsg db " --- Assembler Pure and Simple --- ",0
mylabel:
invoke MessageBox, 0, ADDR szMsg, ADDR szDlgTitle, MB_OK
invoke ExitProcess, 0
end start
instead of:
.data
szDlgTitle db "Minimum MASM", 0
szMsg db " --- Assembler Pure and Simple --- ",0
.code
start:
invoke MessageBox, 0, ADDR szMsg, ADDR szDlgTitle, MB_OK
invoke ExitProcess, 0
end start
In my opinion, the second version looks cleaner. What's the advantage of using jmp over the constant data instead of moving the constant data in the .data segment?
This might look like a trivial question, but, as many people suggested me on this forum, I need to form a style from the very beginning. I am tempted to think there are some reasons I don't understand now for people writing code that looks unnecessary complicated to me.
Sergiu,
It was a trick long ago to write data in the code section so you did not add a data section, it used to save you 512 bytes. In a serious app you put data in the .DATA section and with UNICODE you can put string data in the resource section in a string table.
"In my opinion, the second version looks cleaner"
You can avoid jmp mylabel1 too...
.code
szDlgTitle db "Minimum MASM",0
szMsg db " --- Assembler Pure and Simple --- ",0
start:
invoke MessageBox, 0, ADDR szMsg, ADDR szDlgTitle, MB_OK
invoke ExitProcess, 0
end start
Adding to Lingo's example:
include \masm32\include\masm32rt.inc
.code
AppName db "Masm32:", 0
HelloW db "Hello World", 0
SayWow db "A box, wow", 0
SayHi db "Hi", 0
ZeBox: MsgBox 0, offset SayWow, offset SayHi, MB_OK
start: MsgBox 0, offset HelloW, offset AppName, MB_OK
exit
end start ; use this one to see only the code after start:
; end ZeBox ; use this one to see the code after ZeBox:
The assembler starts executing at the label that matches end xxx. We routinely use start: here in the forum, but ZeBox or Main or main work, too. If you have only a few initialised data, you can use the space between .code and start: to insert them without creating an extra .data section. It saves a few bytes: with linker option /MERGE:.rdata=.text it assembles at 1024 bytes.
the .CONST and .CODE segments are write-protected
any attempt to write to those areas will generate an access privilege exception
(this can be altered by using the VirtualProtect API function)
data is generally placed in one of these segments to prevent "accidental" modification
each segment added to the PE EXE adds 512 bytes to the size of the file
so, instead of creating a new .CONST segment, placing protected data in the .CODE segement saves 512 bytes
if you wanted to, you could place all the initialized data in the .CODE segment
then, during program initialization, use VirtualProtect to enable read-write access to the desired area
Quote from: dedndave on March 09, 2010, 10:36:07 AM
if you wanted to, you could place all the initialized data in the .CODE segment
then, during program initialization, use VirtualProtect to enable read-write access to the desired area
alternatively you can declare the code segement as writeable at top of file (before .model):
_TEXT SEGMENT WRITE EXECUTE
_TEXT ENDS
good one qWord
i didn't know the right way to do that :P
i have just modified the PE header - lol
there is one flaw on using SEGMENT: an second empty code segment is generated (the linker also warn about that). This cause the EXE to grow about the size of PE's section alignment, which is mostly 512 Bytes.
Like jj said, polink's merge is the best option in such case.
Quote from: BlackVortex on March 09, 2010, 08:24:58 PM
Like jj said, polink's merge is the best option in such case.
My notic was about making code section writable, not about section combining :bg
BTW: this can also be done with linker: '/SECTION:.text,EW'
512 bytes? Who cares? Do it the right way and put constant data in a .CONST segment.
Quote from: Greg Lyon on March 09, 2010, 10:16:20 PM
512 bytes? Who cares? Do it the right way and put constant data in a .CONST segment.
I agree, 512 bytes is effectively nothing.
Quote from: BlackVortex on March 09, 2010, 08:24:58 PM
Like jj said, polink's merge is the best option in such case.
/MERGE:.rdata=.text works wth MS link.exe, too - 1024 bytes. The practical value is limited, of course, but sometimes it's cute to take symbolic action against the bloat ;-)
Screw practicality, I'm using xor eax,eax \ inc eax instead of mov eax,1 !!!
(http://img46.imageshack.us/img46/5861/bigbadgrin.gif)
it would be much more fun to use AND EAX,1
that way, you get a random bug :bg
sometimes it is 1
sometimes it is 0
we can call it "maybe logic"
maybe it is - eh - maybe it isn't
Try
or eax, -1
and eax, 1
A bit longer but less "maybe" ;-)
Or, for positive values only please:
cdq
div eax
3 bytes only, and you get a free GPF in case eax was negative.
push 0
pop eax
(3 bytes)