Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating named variables in the stack

Is there any way to create named variables in the stack rather refer to them by offset:

sub esp, 0x10 ; 4 variables of 4 bytes

mov DWORD [ebp-4], 0xf ; 1st var
mov DWORD [ebp-8], 0xff  ; 2nd var
; and so on
like image 330
Kevin Avatar asked Feb 21 '17 11:02

Kevin


People also ask

How are variables placed on the stack?

The stack is used for dynamic memory allocation, and local variables are stored at the top of the stack in a stack frame. A frame pointer is used to refer to local variables in the stack frame.

Can we create two variables same name?

Said in simple terms, if multiple variables in a program have the same name, then there are fixed guidelines that the compiler follows as to which variable to pick for the execution.


1 Answers

FASM

FASM supports local variables through ad-hoc crafted macros that are shipped with FASM itself.

include 'win32ax.inc' 

.code

  start:
        mov ax, 1

        call foo


  proc foo

      ;Local variables

      locals
        var1 dd ?
        var2 dw ?
      endl


      ;Use them as expected
      mov eax, [var1]
      lea ebx, [var2]

   ret
  endp 

That is compiled1 into

:00401000 66B80100                mov ax, 0001
:00401004 E800000000              call 00401009
:00401009 55                      push ebp
:0040100A 89E5                    mov ebp, esp
:0040100C 83EC08                  sub esp, 00000008
:0040100F 8B45F8                  mov eax, dword ptr [ebp-08]
:00401012 8D5DFC                  lea ebx, dword ptr [ebp-04]
:00401015 C9                      leave
:00401016 C3                      ret

NASM

NASM support local variables too with the use of the %local directive.

Quoting from the manual:

silly_swap: 
    %push mycontext             ; save the current context 
    %stacksize small            ; tell NASM to use bp 
    %assign %$localsize 0       ; see text for explanation 
    %local old_ax:word, old_dx:word 

    enter   %$localsize,0   ; see text for explanation 
    mov     [old_ax],ax     ; swap ax & bx 
    mov     [old_dx],dx     ; and swap dx & cx 
    mov     ax,bx 
    mov     dx,cx 
    mov     bx,[old_ax] 
    mov     cx,[old_dx] 
    leave                   ; restore old bp 
    ret                     ; 

    %pop                        ; restore original context

The %$localsize variable is used internally by the %local directive and must be defined within the current context before the %local directive may be used.

Other sloppy approaches

One could

%define SUPER_VAR ebp-4
%define MEGA_VAR ebp-8

mov DWORD [SUPER_VAR], 0xf
mov DWORD [MEGA_VAR], 0xff

However this hides the fact that the variables are in the stack and assume a correctly set frame pointer.

A slightly better approach:

%define SUPER_VAR 4
%define MEGA_VAR 8

mov DWORD [ebp-SUPER_VAR], 0xf
mov DWORD [ebp-MEGA_VAR], 0xff

The assembly programmer way

Real assembler programmers use comments[citation needed] to state the intentions of their code.
And write code only in vi. Or it was emacs?

mov DWORD [ebp-4], 0xf           ;SUPER_VAR
mov DWORD [ebp-8], 0xff          ;MEGA_VAR

The key strengths of the assembly language are its simple syntax and the full information approach (nothing is hidden, the programmer controls everything).

While there is nothing wrong with using high-level macros2, mixing high and low level approaches result in a source file that is harder to parse for an expert.

Furthermore it makes little sense from an ontological point of view: if you want to use high-level features then a language like C is better suited and the use of assembly must be reconsidered. Au contraire, if you want to learn how to do low-level programming then such macros are an hindrance to the learning process.

Finally, macros are not magic. While very flexible soon or later a programmer will encounter their limit.
For example, I haven't dug into the FASM and NASM support for aligned local variables.


1 At this point this is not assembly anymore...
2 High-level macros let you refactor the code easily, which is very important. One should pause a moment though, questioning itself about the choice made of using assembly when important refactoring is expected/needed.

like image 127
Margaret Bloom Avatar answered Sep 19 '22 02:09

Margaret Bloom