0
votes

Lets say I have a PROC in My assembly code like so:

.CODE
PROC myProc
MOV EAX, 00000001
MOV EBX, 00001101
RET
ENDP myProc

I want to MOV 1, into the EAX register, and move 13 into the EBX register in my procedure, however I want to create two variables local to my PROC, assigning var a the value of 1, and var b the value of 13, and from there MOVing [a] into EAX, and [b] into EBX. I have had many ideas about this before, perhaps creating space on the stack for the variables, or something like:

.CODE
PROC myProc
PUSH ESP
PUSH EBP
MOV ESP, 00000001
MOV EBP, 00001101
MOV EAX, [ESP]
MOV EBX, [EBP]
ENDP myProc

But this still really isn't dynamic variable creation, I am just writing and reading data back and forth between registers. So in essence I am trying to figure out how to create variable in assembly at run-time. I would appreciate any help.

2
Your second example is nonsense. If you assign a constant to the stack pointer, you've lost your only reference to the place where you pushed ESP and EBP. Also, mov eax, [001] is just going to fault on a bad address. I also don't see any register-to-register moves in your second example, so IDK what you think it does, but it's not "writing and reading data back and forth between registers." - Peter Cordes
If you want dynamic memory space for storing some values into, for small sized thing (up to few kiB), you can usually reserve that space on the stack, that's what C does. At the beginning of PROC one of the prologue instructions may be sub esp,<size_of_temporary_space>, and before ret you restore the esp (releasing that space). In between you can address it through [esp+<0 .. size-1 offset>], although usually the ebp is used for this. If you want huge (kiB -> MiB/GiB) dynamic memory space, check your API for heap allocation. "Variables" => call it whatever you wish, not important. - Ped7g

2 Answers

4
votes

Variables are a high-level concept. An asm implementation of a C function will typically have a variable live in a register for some of the time, but maybe at other times it's live in a different register, or in memory at some location once it's no longer needed (or you ran out of registers).

In asm you don't really have variables (other than static storage), except by using comments to keep track of what means what. Just move data around and produce a meaningful result.

Avoid memory whenever possible. Look at C compiler output: any decent compiler will keep everything in registers as much as possible.

int foo(int a, int b) {
  int c = a + 2*b;
  int d = 2*a + b;
  return c + d;
}

This function compiles to the following 32-bit code with gcc6.2 -O3 -fverbose-asm (on the Godbolt compiler explorer). Notice how gcc attaches variable names to registers with comments.

    mov     ecx, DWORD PTR [esp+4]    # a, a
    mov     edx, DWORD PTR [esp+8]    # b, b
    lea     eax, [ecx+edx*2]  # c,
    lea     edx, [edx+ecx*2]  # d,
    add     eax, edx  # tmp94, d
    ret
1
votes

It seems like you're using MASM syntax. The standard MASM approach to create local variables is

.CODE
  PROC myProc
    LOCAL a: DWORD
    LOCAL b: DWORD
    ; Initialize those vars
    MOV a, 00000001
    MOV b, 00001101
    RET
  ENDP myProc

The LOCAL directive creates space on the stack for the variables using EBP relative indexing.