Is there any way to create a variable in the .code section, instead of .data? I simply feel limited, in that I can't make a variable on the fly.
2 Answers
It sounds like what you're asking is, can you dynamically allocate space at runtime. The answer is yes and one of the most common methods is;
int Func ()
{
int Distance;
Distance = 132;
}
in assembly this would look like
push rbp
mov rbp, rsp
sub rsp, 8 Now RSP points to what is essentially Distance
mov dword [rbp-8], 132
Another value could be stored @ [rbp-4] as dwords only require 4 bytes.
There are several other ways of allocating space, maybe modify your question to be more specific on what you need and then either I or someone else can give you an example based on that.

- 1,208
- 8
- 17
-
If I wanted to do this with text, would anything change? Or would I just have to do 13, 10, "Message$" ? – Keto Z Sep 24 '16 at 17:21
-
What I'm trying to do is almost make a "skeleton" for all of my MASM programs. So, I'm creating a whole bunch of macros for things like printing, adding, subtracting, et cetera. I'd like to make another macro for creating variables (just like a high-level language, so I can type "int [name]" and then use that variable) – Keto Z Sep 24 '16 at 17:44
-
Most often what you're referring to is called a _template_. Although doable, it does reach far beyond the scope of *SO*, which is more oriented to specific questions. – Shift_Left Sep 24 '16 at 17:55
i dont know for other assemblers but in tasm, im using this macro, like this one that, saves the address of certain variable on the stack,
@pushsz macro msg2psh, empty
local next_instr
ifnb <empty>
%out too many arguments in macro '@pushsz'
.err
endif
call next_instr ; pushes the address of the message as the return address
db msg2psh,0
next_instr:
endm
you can use it like this:
push 0
@pushsz "hello world"
@pushsz "some text"
push 0
call MessageBoxA
as you can see, the strings are encoded along with the instructions, of course you can use not only string but other types as well, However be aware that this technique modifies the stack, (see the stdcall example above), so you should pop it off or restore the stack after use.
Another thing to consider is the read/write access of the memory, if the memory is not writable and you save something in it, an exception will occur. the macro given assumes data are read only, here's another example:
@pushsz "My Stringzero here"
pop eax ; eax contains the address of the string
i think its not hard to convert this for MASM macro syntax, sorry not a masm user, i got this technique here https://vxheaven.org/29a/29a-2/29a-2.3_3

- 328,167
- 45
- 605
- 847

- 112
- 1
- 4
-
Holy crap that's a horrible abuse of `call` to push the address of the string as a return address. It will perform badly on modern CPUs, since [mismatched call/ret breaks the return-address predictor stack.](http://stackoverflow.com/questions/22442766/return-address-prediction-stack-buffer-vs-stack-stored-return-address). – Peter Cordes Sep 23 '16 at 02:36
-
Much better would be to put the message in the `.rodata` section and just `push` its address normally. You could still do that all with one macro (switch to `section .rodata`, db the string, and switch back to whatever section you were in before). The linker will gather all strings together in the read-only data section, and leave the code uninterrupted by data. – Peter Cordes Sep 23 '16 at 02:39
-
I see you got that trick from a DOS example. It's an interesting idea if code-size is the only thing that matters. It's questionable for performance even on old CPUs, though, since anything with split L1 I and D cache will need the line holding the string in D cache as well as I cache when something reads the string. It's also only useful for bad old ABIs where args are passed on the stack instead of registers. It's a cool idea for 286 or 386 era CPUs, but it's not a good idea now. – Peter Cordes Sep 23 '16 at 02:43